开发者

Weird problem using UINib / pointer going AWOL

开发者 https://www.devze.com 2023-01-16 07:54 出处:网络
I have something weird going on with using UINib, although I suspect the real problem may be buried elsewhere.

I have something weird going on with using UINib, although I suspect the real problem may be buried elsewhere.

My app is using a tableview, the content for the cells has been prepared in Interface Builder due to their complexity. For new cells (as opposed to reused ones), the contents of the nib are instantiated using the UINib Class. Because there is only one nib used for all cells and to reduce the overhead from loading the file each time, I added an UINib as a property cellNib to my viewcontroller subclass which I load once in my implementation of viewDidLoad.

Now for the weird part. Everything is working fine, the tableview is populated with its data and all cells are set up with the contents of the nib as they should be. But as soon as i scrol开发者_如何转开发l the tableview, the application crashes.

The callstack gave this away: -[NSCFNumber instantiateWithOwner:options:]: unrecognized selector sent to instance Obviously, the message to instantiate the contents from cellNib again has been sent to the wrong object. The object to which the message is being sent differs from time to time, so there is something random going on.

I don't get it - why is it working about 10 times while loading the tableview, but not anymore when the tableview is being scrolled?

If I create a new instance of UINib each time (as seen in my code below), then everything is working just fine, scrolling included.

Where do I make a mistake? Is the pointer of my UINib property going awol? If so, why??

Here's the code I'm using (I removed all the data loading and other stuff to make it easier to read):

@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

The implementation:

@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;
}

Thanks alot!!


This line assigns an autoreleased instance to cellNib:

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

This means that with the following line:

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

... cellNib is already deallocated when its associated autorelease pool was drained and using it will result in undefined behaviour.

If you want cellNib to stay around take ownership of it, e.g. by using the declared property:

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

精彩评论

暂无评论...
验证码 换一张
取 消