cellDidForRowAtIndexPath方法为什么有时候不调用?

本文详细介绍了在使用UITableView时遇到的一个Bug,即cellDidForRowAtIndexPath委托方法在多次实例化ViewController后无法正常调用。通过分析代码和调试过程,作者发现了问题源于Interface Builder对.nib文件加载行为的优化。为了规避此问题,提出了一种解决方案,即在头文件中声明并初始化ViewController作为成员变量,确保只加载一次nib文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UITableView中存在一个Bug,cellDidForRowAtIndexPath委托方法有时候不会调用。具体表现为,第1次实例化ViewController时(加载nib文件)时,reloadData会调用委托方法中的cellDidForRowAtIndexPath方法。而再次实例化一个ViewController对象,reloadData方法就不会触发cellDidForRowAtIndexPath调用了。测试环境为Xcode4.2和SDK 4.3。模拟器和真机都是一样的。

这个Bug还没有人报告给苹果。

进行Debug后发现,IB在多次加载.nib文件时会采取不同的行为。当第1次加载.nib文件时,table view 在reloadData时总是按照numberOfSectionsInTableView-> numberOfRowsInSection -> cellForRowAtIndexPath的顺序调用的。但第2次以后只能按照numberOfSectionsInTableView-> numberOfRowsInSection 来调用。也就是说,在第2次加载nib文件后,数据源方法 cellForRowAtIndexPath 无论如何都不会被调用了。目前还不明白是什么原因。

这种情况是由以下代码造成的:

iPadBindVC* mvc=[[iPadBindVC alloc]initWithNibName:@"iPadBindVC" bundle:nil];

mvc.delegate=self;

[self presentModalViewController:mvc animated:YES];

iPadBindVC含有一个Table View,在viewDidLoad方法的时候我会reloadData这个TableView以便加载一些数据。当以上代码第1次运行时,bebug代码发现,数据源方法cellForRowAtIndexPath被调用了,同时TableView会呈现出数据:

当第2次运行以上代码时,debug代码发现数据源方法cellForRowAtIndexPath不会被调用(但是调用了 numberOfSectionsInTableView和 numberOfRowsInSection ),导致出现一个空白的Table View:

第3次、第4次⋯⋯仍然如此。

我猜测这是苹果对.nib的加载进行了优化的原因。导致第一次加载和多次加载.nib时会有不同的行为。我们可以调整上述代码,“暂时”回避这个bug:

if(vc==nil){

vc=[[iPadBindVC alloc]initWithNibName:@"iPadBindVC" bundle:nil];

vc.delegate=self;

}

[self presentModalViewController:vc animated:YES];

NSLog(@"retaincount:%d",[vc retainCount]);

vc现在变成了一个成员变量,在头文件中声明。也就是说,我们只会加载一次nib文件。如果vc已经从nib文件中构造出来,我们直接present它而不再重新构造。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值