您的位置:首页 > 移动开发 > Objective-C

Memory Management in Objective-C Tutorial 读后小记

2012-09-15 10:18 393 查看


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
 
}

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

自认为目前为止,对这套机制了解的还算可以,也就懒得看了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息