使用UINib /指针AWOL的奇怪问题

时间:2010-09-17 09:35:38

标签: iphone objective-c pointers nib

我使用UINib时遇到了一些奇怪的事情,尽管我怀疑真正的问题可能会被埋没在其他地方。

我的应用程序正在使用tableview,由于其复杂性,已在Interface Builder中准备了单元格的内容。对于新单元格(与重用单元格相对),使用UINib Class实例化nib的内容。因为每个单元只有一个nib用于减少每次加载文件的开销,所以我将一个UINib作为属性cellNib添加到我的viewcontroller子类中,我在viewDidLoad的实现中加载了一次。

现在是奇怪的部分。一切都工作正常,tableview填充了它的数据,所有单元格都设置了nib的内容。但是当我滚动tableview时,应用程序崩溃了 callstack给出了这个: - [NSCFNumber instantiateWithOwner:options:]:无法识别的选择器发送到实例 显然,再次从cellNib实例化内容的消息已被发送到错误的对象。发送消息的对象不时会有所不同,因此会随机发生。

我没理解 - 为什么在加载tableview时它会工作大约10次,但是当滚动tableview时它不再工作了?

如果我创建一个新的UINib 每个时间的实例(如下面的代码所示),那么一切正常,滚动包含。

我在哪里犯错?我的UINib属性的指针是否会变形?如果是这样,为什么??

这是我正在使用的代码(我删除了所有数据加载和其他内容以便于阅读):

@interface NTDPadViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {

   NSManagedObjectContext *managedObjectContext;
   NSMutableArray *ntdArray;
   IBOutlet UITableView *ntdTableView;
   UINib *cellNib;

}

@property(nonatomic,retain) NSManagedObjectContext *managedObjectContext;
@property(nonatomic,retain) NSMutableArray *ntdArray;
@property(nonatomic,retain) UITableView *ntdTableView;
@property(nonatomic,retain) UINib *cellNib;

@end

实施:

@implementation NTDPadViewController

@synthesize managedObjectContext;
@synthesize ntdArray;
@synthesize ntdTableView;
@synthesize cellNib;

-(void)viewDidLoad {

   [super viewDidLoad];
   cellNib = [UINib nibWithNibName:@"NTDCell" bundle:nil];

}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

   static NSString *CellIdentifier = @"Cell";

   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
   if (cell == nil) {
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

       [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
       [cell setBackgroundColor:[UIColor clearColor]];

       // These two should work equally well. But they don't... of course I'm using only one at a time ;)
       // THIS WORKS:
       UINib *test = [UINib nibWithNibName:@"NTDCell" bundle:nil];
       NSArray *nibArray = [test instantiateWithOwner:self options:nil];

       // THIS DOESN'T WORK:
       NSArray *nibArray = [cellNib instantiateWithOwner:self options:nil];

       [[cell contentView] addSubview:[nibArray objectAtIndex:0]];

   }

   return cell;
}

非常感谢!!

1 个答案:

答案 0 :(得分:7)

此行将autorelease d实例分配给cellNib

cellNib = [UINib nibWithNibName:@"NTDCell" bundle:nil];

这意味着使用以下行:

NSArray *nibArray = [cellNib instantiateWithOwner:self options:nil];

... cellNib在关联的自动释放池耗尽时已经解除分配,使用它会导致未定义的行为。

如果您希望cellNib留下来取得所有权,例如通过使用声明的属性:

self.cellNib = [UINib nibWithNibName:@"NTDCell" bundle:nil];