Object-C 中的内存管理
· 当你调用alloc/init的时候,你得到一个引用计数是1的对象。
· 当你用完这个对象之后,你要对它调用release消息,使其引用计数为0,这样它的内存才会被释放掉。
· 当你调用一个方法,它不是以init或者copy开头的,这时,返回给你的对象是autorelease的,它是一种在将来某个时刻会自动被释放的对象。(这里我也要提醒大家一句,比如你在写一个函数,它的名字是xxx,没有以init或者copy开头,那么记得你返回的对象一定要是autorelease的,否则,别人在使用你这个函数的时候就会把它当前是autorelease的,那么他就不会release它,这样就会造成内存泄漏,千万要切记!!!)
· 如果你想继续使用autorelease对象,那么你就要给它放送一个retain消息。
· 如果你使用alloc/init方法创建了一个对象,但是你想让它自己在出了runLoop之后被自动释放的话,那么你可以在alloc/init之后再调用autorelease。这也是一种见得比较多的写法了。比如,cocos2d里面调用[xxx node]的时候,就等于[[[xxx alloc] init]autorelease].
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
NSString * sushiName = [_sushiTypesobjectAtIndex:indexPath.row]; // 1
NSString * sushiString = [NSStringstringWithFormat:@"%d: %@",
indexPath.row, sushiName]; // 2
NSString * message = [NSStringstringWithFormat:@"Last sushi: %@. Cur sushi: %@", _lastSushiSelected, sushiString]; // 3
UIAlertView *alertView = [[[UIAlertViewalloc] initWithTitle:@"Sushi Power!"
message:message
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"OK", nil] autorelease]; // 4
[alertView show]; // 5
[_lastSushiSelected release]; // 6
_lastSushiSelected = [sushiString retain];// 7
}
这里的代码比较多,让我们一行一行来看:
1. 查找当前行对应的shshiTypes数组里面的字符串。
2. 根据当前行号构建一个新的字符串。注意,这里使用的是stringWithFormat方法,它返回的是一个autorelease的字符串。因为这个方法并不是以init或者copy开头,所以你就知道。记住,这意味着,你可以在这个函数里面使用此字符串,但是出了这个函数的话,如果你还想继续使用之,那必须要对它发送一个retain消息。
3. 构建一个消息,用来显示当前选中的sushi和最后选中的sushi。和上面一样,这里也是使用的stringWithFormat方法,它返回的是一个autorelease对象。因为我们只想在这个函数里面使用,所以没有retain。
4. 创建一个alertView来显示刚刚构建的那个消息。这里是通过alloc/init方式创建的,所以我们需要在之后再发送一个autorelease消息,这样在出了这个函数以后,这个对象就会被释放掉了。
5. 显示这个alert view。
6. 再你设置lastSushiSelected实例变量之前,你需要先释放当前的lastSushiSelected实例变量,如果当前实例变是已经是nil的话,也没有关系,因上nil对象可以接收任何消息。
7. 因为你想在这个函数之外再使用lastSushiSelected这个字符串,所以你需要retain它。
还有一件事你不能忘记。为了保存不会有任何内存泄漏,你需要在RootViewController的dealloc方法里面调用下面方法来释放内存:
[_lastSushiSelectedrelease];
_lastSushiSelected= nil;
基本上,在dealloc方法被里面,你需要对“你负责的对象”发送release消息,并且要把它赋值为nil。