Natural

 

UITableView滚动时crash

照着网上的教程,吭哧吭哧写好了一个tableView,Run起来,界面出现了。还来不及高兴一下,一滚动,坑爹啊,直接crash掉了,退出。

打开调试模式,再重现一次,Debugger Console显示的结果是“Program received signal: "EXC_BAD_ACCESS"”.
这个结果表示代码中有数组越界或者哪里内存泄漏了。(网上教程不靠谱啊,完全照着教程敲代码竟然都错了)

还好总共没几个方法,多加几个断点调试一下。
问题出来了:当向下滚动,调用cellForRowAtIndexPath消息时,执行到第25行代码tableData已经被回收了。

问题分析:
数组初始化放在viewDidLoad消息中,照着教程敲使用arrayWithObjects来创建。从语法上讲,此方法是autorelease的,不需要我们手动去release。
然而问题也出在这,当向下滚动时,不知为何在viewDidLoad初始化的数组都已经被回收了。

修正方案:
把viewDidLoad消息中数组创建方法都改为[[NSArray alloc] initWithObject: ……];方式创建,再在dealloc中释放掉就OK了。

推断总结:
此代码的界面是用IB拉出来的,对于新人来说我们并不清楚它的view的创建细节。从执行效果来看,它在创建view时嵌套了个NSAutoreleasePool,向下滚动时已经把pool给release掉了,所以出现crash。

得到教训就是:使用IB创建界面时,那些自定义的对象尽量使用alloc/retain/copy方式创建,自己release。把内存管理寄托在自动释放池中是不靠谱的,除非这个池是你自己创建并释放的。


源代码如下
 1 
 2 - (void)viewDidLoad {
 3     [super viewDidLoad];    
 4     tableData = [NSArray  arrayWithObjects:@"香辣酱香骨",@"肉末烧豆腐",@"芙蓉虾",@"红烧带鱼",
 5                  @"粉蒸排骨",@"自来红月饼",@"蛋黄莲蓉月饼",@"南瓜奶酪蛋糕",
 6                  @"南瓜沙拉",@"五香毛豆",@"奶油冰淇淋",@"焦糖南瓜冰淇淋",nil];
 7     thumbnails =[NSArray arrayWithObjects:@"a.jpg",@"b.jpg",@"c.jpg",@"d.jpg",@"e.jpg",@"f.jpg",
 8                   @"g.jpg",@"h.jpg",@"i.jpg",@"j.jpg",@"k.jpg",@"l.jpg",nil];
 9     prepTime = [NSArray arrayWithObjects:@"10 min",@"5 min",@"5 min",@"10 min",@"8 min",@"30 min",
10                   @"30 min",@"45 min",@"20 min",@"5 min",@"50 min",@"40 min",nil];
11 }
12 
13 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
14     return [tableData count];
15 }
16 
17 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
18     static NSString *simpleTableIdentifier = @"SimpleTableItem";
19     SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
20     if(cell == nil){
21         NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"SimpleTableCell" owner:self options:nil];
22         cell = [nib objectAtIndex:0];
23     }
24     NSUInteger row = [indexPath row];
25     cell.nameLabel.text = [tableData     objectAtIndex:row];
26     cell.thumbnailImageView.image = [UIImage imageNamed:[thumbnails objectAtIndex:row]];
27     cell.prepTimeLabel.text = [prepTime objectAtIndex:row];
28     return cell;
29 }
30 
31 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
32     return 78;
33 }
34 
35 - (void)dealloc {
36     [super dealloc];
37 }

posted on 2012-09-07 11:33 此号已被删 阅读(992) 评论(0)  编辑  收藏 所属分类: Objective-C


只有注册用户登录后才能发表评论。


网站导航:
 

导航

统计

常用链接

留言簿(8)

随笔分类(83)

随笔档案(78)

文章档案(2)

相册

收藏夹(7)

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜