【问题标题】:Weird problem using UINib / pointer going AWOL使用 UINib / 指针离开的奇怪问题
【发布时间】:2010-09-17 09:35:37
【问题描述】:

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

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

现在是奇怪的部分。一切正常,tableview 填充了它的数据,并且所有单元格都设置了 nib 的内容,因为它们应该是。但是,一旦我滚动 tableview,应用程序就会崩溃。
调用堆栈给出了这个:-[NSCFNumber instantiateWithOwner:options:]: unrecognized selector sent to instance 显然,再次从 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;
}

非常感谢!!

【问题讨论】:

    标签: iphone objective-c pointers nib


    【解决方案1】:

    这一行将autoreleased 实例分配给cellNib

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

    这意味着使用以下行:

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

    ...cellNib 在其关联的自动释放池耗尽时已被释放,使用它将导致未定义的行为。

    如果您希望 cellNib 留下来,请拥有它,例如通过使用声明的属性:

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

    【讨论】:

    • 你说得对。它现在正在工作。您能否解释一下为什么 cellNib = 和 self.cellNib = 之间有区别?我一直认为在对象通过 self 引用属性的上下文中。是“可选的”...(愚蠢的我)
    • @Toastor:这两个变体做完全不同的事情。 self.cellNib = ... 是调用在您的情况下保留的设置器的“点语法”。 cellNib = ... 只是直接赋值给 ivar,覆盖之前的指针值。有关详细信息,请参阅 Apple 文档中的 declared properties section
    猜你喜欢
    • 2015-07-17
    • 2011-03-09
    • 1970-01-01
    • 2013-02-04
    • 2023-04-07
    • 1970-01-01
    • 2017-02-07
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多