Memory Management in Objective-C Tutorial 读后小记


Memory Management in Objective-C Tutorial


看过一些中文教程,在这个分类里面也有收录。发现写的真的不行,我又忍不住崇洋媚外了。看一下,这篇,来refresh this topic。这是这个系列的第一篇,嗯,今天把这个系列看完,让自己的代码更加规范。

2和3也很让人期待。

小技巧1:

- (void)viewDidUnload {
    [_sushiTypes release];
    _sushiTypes = nil;
}
 
- (void)dealloc {
    [_sushiTypes release];
    _sushiTypes = nil;
    [super dealloc];
}

Note that you also set the object to nil afterwards. This is a good practice, because by setting it to nil it avoids a lot of problems. Any time you call a method on a nil object, it does nothing, but if you don’t set it to nil, if you tried calling a method on a deallocated object your program should crash.

现在知道这么做的原因了。但是如果程序中写的比较乱,在别的实体中的变量浅拷贝了这个被set成nil的实例变量,别的实体中的变量就变成没人管的野指针了,所以如果涉及到这种值传递,必须深拷贝。特别是容器类型的变量,还得考虑容器里面的元素。比较麻烦。个人浅见。



小细节2:

我擦,还真是让我解了个疑惑,有收获,出去买菜先,回来继续看。



NSString * sushiName = [_sushiTypes objectAtIndex:indexPath.row]; // 1
NSString * sushiString = 
    [[[NSString alloc] initWithFormat:@"%d: %@", 
        indexPath.row, sushiName] autorelease]; // 2
cell.textLabel.text = sushiString; // 3

Sometimes when you call methods, they return objects to you that have a retain count of 1, but have an autorelease pending. You can see what I mean by modifying tableView:cellForRowAtIndexPath underneath where it says “Configure the cell” once more to look like the following:

NSString * sushiName = [_sushiTypes objectAtIndex:indexPath.row]; // 1
NSString * sushiString = 
    [NSString stringWithFormat:@"%d: %@", 
        indexPath.row, sushiName]; // 2
cell.textLabel.text = sushiString; // 3

The change here is just in line 2. Instead of calling alloc/init/autorelease, you now call a helper method on NSString called stringWithFormat. This method returns a new NSString with a retain count of 1, but has an autorelease pending. So just like the last example, it’s OK to use the string here, but you’d better not save it and try to use it again somewhere else (without retaining it) or the app might crash.

在此加入个人理解,个人理解都是中文写的,太好区分了。

上面第二种写法,没有alloc也没有 没有autorelease 直接用 stringWithFormat方法,产生的sushiString 自带一个autorelease。与上面那个先alloc再显示autorelease 完全相同。看了第二篇的例子,有了新的理解,貌似略微有点不同。不是很理解它的这个术语next run loop。原文如下“

Well sushiString looks OK, because it’s initialized with stringWithFormat (which returns an autorelease variable), so it should be safe to use until the next run loop. But what about _lastSushiSelected?

_lastSushiSelected was set the last time this method was run to sushiString. But sushiString is an autorelease variable, so at some point it will be released, and the memory will be deallocated.”我的理解,如果显示调用autorelease的话,应该是在autorelease pool release 的时候才release的。待验证啊待验证。

通过实验验证。目前就autorelease的时机有待查证,貌似不是我之前理解的那样。继续追求真想~~~~~~~~~~~~~~~~~~~~~~

You might wonder how you can if a method returns an object with an autorelease pending or not. Well, there’s a simple convention that can tell you the answer to that:

  • If the method name begins with init or copy, the object returned will have a retain count of 1, and no autorelease pending. In other words, you own that object and have to release it when you’re done.
  • If the method name begins with anything else, the object returned will have a retain count of 1, and an autorelease pending. In other words, you can use the object right now, but if you want to use it later you have to retain the object.
小细节3:

Next modify tableView:didSelectRowAtIndexPath as follows:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 
    NSString * sushiName = [_sushiTypes objectAtIndex:indexPath.row]; // 1
    NSString * sushiString = [NSString stringWithFormat:@"%d: %@", 
        indexPath.row, sushiName]; // 2
 
    NSString * message = [NSString stringWithFormat:@"Last sushi: %@.  Cur sushi: %@", _lastSushiSelected, sushiString]; // 3
    UIAlertView *alertView = [[[UIAlertView alloc] 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. Before you can set the lastSushiSelected instance variable, you need to release the current lastSushiSelected object. If lastSushiSelected is nil, it’s OK, this will just do nothing.这是第六行的解释,依稀可以看到retain property的属性了。

最后是总结:

When you call a method that begins with anything except init or copy, you’re returned an object that will be autoreleased at some point in the future.

我勒个去,我还没在中文的文档里面看到过这句话,搞得我现在才明白。

顺便展望一下第二篇,how to debug memory leaks using XCode, Instruments, and Zombies.Instruments不会用,正好看看。

最后也把苹果官方的连接放在这里,

Advanced Memory Management Programming Guide

自认为目前为止,对这套机制了解的还算可以,也就懒得看了。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值