iOS 有关内存管理的一个错误分析
今天遇到一个错误,定义了一个全局NSMutableArray *arry;
- (void)viewDidLoad { NSLog(@"viewDidLoad"); [super viewDidLoad]; self.navigationItem.title = @"familyName"; //arry = [[NSMutableArray arrayWithCapacity:5]retain]; arry = [[NSMutableArray alloc] init]; MyCellContent *content0 = NEWCELLCOTENT(@"0.png",@"0000"); MyCellContent *content1 = NEWCELLCOTENT(@"1.png",@"1111"); MyCellContent *content2 = NEWCELLCOTENT(@"0.png",@"1111"); MyCellContent *content3 = NEWCELLCOTENT(@"1.png",@"1111"); MyCellContent *content4 = NEWCELLCOTENT(@"0.png",@"1111"); [arry addObject:content0]; [arry addObject:content1]; [arry addObject:content2]; [arry addObject:content3]; [arry addObject:content4]; }
后面用到它
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //尝试从重用队列中取出一个cell,如果返回nil,就要重新创建一个 static NSString *CellIdentifier = @"BaseCell"; MyCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if(!cell) { cell = [[MyCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } [cell fillCell:[arry objectAtIndex:indexPath.row]]; return cell; }
运行时完全正常,但是当把cell滑出可视范围时,就会崩溃。看调试信息,得知arry:0 object,arry 居然是空的!
思考:我明明定义的是全局的、又添加进了object,这里arry为什么会为空了?
求问于前辈,得知犯了明显的内存管理的错误。上面的代码是已经修改过的代码。
我原本是这样定义arry的:arry = [[NSMutableArray arrayWithCapacity:5];没有加retain。
这样导致的问题就是:非采用new,alloc,copy创建的对象,系统会自动把它设为autorelease。
当这个对象所在的方法执行完后,系统就会在某一不确定的时间release掉arry对象,所以我们得到的arry为空。
汲取教训:在ios开发中,尽量采用new,alloc,copy创建的对象,不要用系统会自动autorelease的对象。
如果非要用别的方式创建对象,那么,请一定加上retain。并注意用完后,要自己写release。
推荐:arry = [[NSMutableArrayalloc] init];
不推荐:arry = [[NSMutableArray arrayWithCapacity:5]retain];
会导致错误的: arry = [[NSMutableArray arrayWithCapacity:5];