@property/@synthesize question
我正在阅读关于内存管理的所有文档,我有点困惑。
使用@property时,它会为对象创建getter/setter:
h:@属性(保留,非原子)nScord*MyS字符串
M:@合成字符串
我明白这一点,但我困惑的是自我的使用。我在不同的博客和书籍中看到了不同的语法。我见过:
1 | myString = [NSString alloc] initWithString:@"Hi there"]; |
或
1 | self.myString = [NSString alloc] initWithString:@"Hi there"]; |
然后在Dealloc中我看到:
1 | self.myString = nil; |
或
1 | [myString release]; |
或
1 2 | self.myString = nil; [myString release]; |
在这个网站上,有人说使用self会给保留计数增加一个增量?是真的吗,我哪儿也没见过。
是否提供自动释放的自动getter/setter?
这一切的正确方法是什么?
谢谢!
如果不使用点语法,则不使用任何setter或getter。
接下来,它取决于如何声明该属性。
假设如下:
1 2 3 | @property (nonatomic, retain) Article *article; ... @synthesize article; |
为文章分配内容
1 | self.article = [[Article alloc] init]; |
将过度保留alloc/init返回的实例并导致泄漏。这是因为文章的设置者将保留它,并将为您释放以前的任何实例。
所以你可以把它改写为:
1 | self.article = [[[Article alloc] init] autorelease]; |
这样做
1 | article = [[Article alloc] init]; |
也可以,但可能涉及泄漏,因为文章可能已经包含了对实例的引用。因此需要提前释放值:
1 2 | [article release]; article = [[Article alloc] init]; |
释放内存可以用
1 | [article release]; |
或与
1 | self.article = nil; |
第一个直接访问字段,不涉及setter/getter。第二个使用setter将字段设置为nil。如果在将当前实例设置为nil之前有一个实例,它将释放当前实例。
这个构造
1 2 | self.myString = nil; [myString release]; |
只是太多了,它实际上发送到零释放,这是无害的,但也不必要。
您只需在心理上使用点语法映射帽子,使用访问器方法:
1 2 3 | self.article = newArticle // is [self setArticle:newArticle]; |
和
1 2 3 | myArticle = self.article; // is myArticle = [self article]; |
关于阅读的一些建议,苹果公司的所有官方文件:
目标C程序设计语言
- 点语法
- 声明的属性
内存管理编程指南
- 物的所有权和处置
- 使用访问器方法
除了尼克的回答之外——合成的getter/setter不提供autorelease(顺便说一句,做这个有什么大主意?好吧,可以将getter用作工厂,但在目标C中这不是一种常见的方法)。
Then in dealloc I see:
self.myString = nil;
or
[myString release];
or
self.myString = nil; [myString
release];
在DealLoc中,使用哪种发布形式并不重要。但最好的办法是在释放它们的时候将你的字段置为零:)我更喜欢在dealoc中使用
当您创建一个
1 2 3 4 5 6 7 | - (void)setString:(NSString *)someString { if (someString != string) { [string release]; [someString retain]; string = someString; } } |
如果不使用setter,则新值不会得到保留值,也不会"拥有"该字符串,因为它是所有引用,如果释放原始字符串,则可能会面临空引用,这将导致
你不应该在setter中使用
至于dealloc,请通过该setter进行跟踪。如果你直接发送一个
根据惯例,我在我的
希望这有帮助!