IBOutlet UITextView 在调用另一个类 initWithNibName 并使用方法返回类后为零

Posted

技术标签:

【中文标题】IBOutlet UITextView 在调用另一个类 initWithNibName 并使用方法返回类后为零【英文标题】:IBOutlet UITextView is nil after calling another class initWithNibName and back to the class using method 【发布时间】:2012-07-20 11:27:02 【问题描述】:

我的问题是在 ProductNoteUIButton Action 我做了initWithNibName Notes Class 以显示带有@987654323 的 popOver 笔记类中的@。我正在从sqlite 获取数据,然后将其加载到tableViewDidSelectRowAtindexPath: 中的UITableView。我得到了 selectedNote 并创建了 ProductNote Class 的对象来调用只设置 IBOutlet's textview.textselectedNote 实例方法但它为零。那是我的问题,下面是代码,请帮助我了解为什么我会遇到此类问题。我正在使用 Xcode 4.3.3 而不是 ARC。我在每个 ViewController 上手动定义了 dealloc 方法

//**ProductNote.h Class****************************
#import <UIKit/UIKit.h>
@class Notes;
@interface ProductNote : UIViewController<UIPopoverControllerDelegate>

UIPopoverController *popOverController;
UITextView *txtmesssagenotes;
Notes *objNotes;

@property (retain, nonatomic) IBOutlet UITextView *txtmesssagenotes; //It is Connected to ProductNote.xib
@property (retain,nonatomic)  UIPopoverController *popOverController; 
@property (retain,nonatomic)  Notes *objNotes;
-(IBAction)presentPopOver:(UIButton*)sender;
 -(void)selectedNote:(NSString*)note;
@end

//ProductNote.m Class
@implementation ProductNote
@synthesize txtmesssagenotes,popOverController,objNotes;

-(IBAction)presentPopOver:(UIButton*)sender

self.objNotes=[[Notes alloc]initWithNibName:@"Notes"bundle:nil];
UIPopoverController *popOver=[[[UIPopoverController alloc]initWithContentViewController:objNotes]autorelease];
self.popOverController=popOver;
self.popOverController.delegate=self;
self.popOverController.popoverContentSize=objNotes.view.frame.size;
CGRect rect=[self.view convertRect:objNotes.view.frame fromView:self.view];
rect.origin.y+=110;
rect.origin.x+=23;
[self.popOverController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:0 animated:YES];
 //Then I get popOver with tableview 

-(void)selectedNote:(NSString*)note

 self.txtmesssagenotes.text=note;     
 //Here I am getting txtmesssagenotes=0X0 or nil. Using self or without self Please tell me the reason.

- (void)dealloc 
[txtmesssagenotes release];
[popOverController release];
[objNotes release];
[super dealloc];

@end

@interface Notes : UITableViewController

NSMutableArray *arrNotes;
NSString *selectedNote;
UITableView *tblNotes;

@property(nonatomic,retain)NSMutableArray *arrNotes;
@property(nonatomic,retain)NSString *selectedNote;
@property(nonatomic,retain)IBOutlet UITableView *tblNotes;
@end

//Actually I skip the other methods that makes larger program to read . other methods only    used to fetch data from sqlite and fill up the arrNotes that is used to fill all rows in the  tableview. 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

 self.selectedNote=[self.arrNotes objectAtIndex:indexPath.row];

//这里self.arrNotes有效对象并包含数据,并将NSString对象赋值给self.selectedNote

ProductNote *productNote=[[ProductNote alloc]init];
[productNote selectedNote:self.selectedNote]; //after calling selectedNote i goto to selectedNote implementation or definition above.
[productNote release];


-(void)dealloc

[arrNotes release];
[selectedNote release];
[tblNotes release];
[super dealloc];

【问题讨论】:

为什么我失去了两个声誉????????????? 因为您问题顶部的文字没有任何标点符号,而且阅读起来很糟糕 - 尝试插入换行符和/或段落:) 仅供参考:如果您正在创建 UIViewController 子类,请将其命名为 somethingViewController - 这样阅读您的代码的人会更快地理解它 :) 例如ProductNote => ProductNoteViewController 【参考方案1】:

这是因为正如您所说,txtmesssagenotes 是使用 IB 创建的。而且您从未展示过您的 ProductNote UIViewController 即时 productNote。因此 txtmesssagenotes 从未正确分配和初始化。

【讨论】:

显示 ProductNote 类的视图后实际上没有。有一个 UiButton 单击它我正在弹出窗口中加载 Notes 类,其中 tableview 显示产品注释类的一些数据。当用户点击 tableview 中的任何行时,我创建 ProductNote 类对象以访问其 selectedNote 实例方法,然后设置 ProductNote 类 IBoutlet textmessagenotes.text 但它 nil.thats 是我今天最头疼的问题 这一行:[productNote selectedNote:self.selectedNote];在您刚刚分配 productNote 后立即使用。因此,在您将您的 productNote 展示/推送到显示堆栈之前,您的所有插座都无法被实例化。 @deanWombourne 的回答非常全面。我会彻底研究他的答案。【参考方案2】:

您是否在视图加载之前调用selectedNote:

仅仅因为您使用 xib 创建了一个视图控制器并不意味着它会立即加载您的所有子视图。

在第一次请求视图控制器的 view 属性时,会解析 xib 并创建所有视图 - 这通常是在它第一次出现之前。

在此之前,所有IBOutlet 连接都将是nil

您需要将笔记的文本存储为视图控制器的NSString 属性。然后,在viewDidLoad 中,您需要调用self.txtmesssagenotes.text=self.note; - 在您的视图加载后会自动调用viewDidLoad,因此您可以保证届时设置所有IBOutlets。

您不应依赖视图对象来存储应用的状态(在本例中为注释文本)。如果在您的视图控制器不可见时收到内存不足警告,那么您的所有视图对象都将被删除 - 只有当您的视图控制器再次可见时才会重新创建它们 - 如果您将注释字符串存储在 UITextView 中,那么它可能下次你请求时不要在那里 :) 你应该始终将数据存储在你的视图控制器(或你控制的其他地方)的一个属性中,并使用它创建你的视图。

【讨论】:

感谢您的回答,但我正在使用 initWithNibName 加载 Notes 类,然后将其添加到 popOverController。您能否尝试理解我的问题,我也发表了评论,请检查。 您的问题(您仍然没有将其格式化以使其易于阅读)是为什么 self.txtmesssagenotes 为零?。 txtmessagenotes 在您使用[[ProductNote alloc]init]; 创建的ProductNote 类中(取自您问题中代码的最后一个sn-p)。为什么你期望它来自 xib? 为什么 self.txtmesssagenotes 为零?是的,这就是我的问题。 txtmesssagenotes 是正在显示的 ProductNote 的 IBoutlet。我在 Notes 类 didselectrowatindexpath 中创建 productNote 类对象只是为了调用 selectedNote 并设置 txtmesssagenotes.text。 您的属性仅在您的视图控制器的视图加载后 创建。您正在调用selectedNote:之前您的控制器的视图已加载。仅仅因为您创建了一个视图控制器并不意味着您已经创建了它的所有视图。 先生,我已经加载了具有 UIButton 的 ProductNotes.xib。通过单击 -(IBAction)presentPopOver:(UIButton*)sender 调用,在 ProductNotes Class.xib 上显示带有 Notes Class.xib 的 PopOver然后我想设置 ProductNote 类的 txtmessagenotes TextView 的文本。通过调用 ProductNotes 类的 selectedNote 方法。它被调用但 textview 仍然为零。非常感谢您的时间和对我的问题的兴趣,但严重的是,我还面临这类问题,让我很头疼。

以上是关于IBOutlet UITextView 在调用另一个类 initWithNibName 并使用方法返回类后为零的主要内容,如果未能解决你的问题,请参考以下文章

iPhone XCode 编程:从导航视图调用的视图未设置其 IBOutlet 属性

UITextView 调用前一个号码

UITextView 不为 iPhone 调整大小

IBOutlet 未在 Cocoa MVC 项目中设置

当从不同的类调用更改时,UIView IBOutlet 不会更改

如何修复 IBOutlet 配置上的 nil 错误和调用 View Controller 时不显示 UI?