UITableView滚动时crash

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  }

你可能感兴趣的:(UITableView滚动时crash)