我已经从不同的来源读到了这样的问题:书籍,文章等,但却无法理解它。当支持的i-vars和属性问题出现以及如何解决时,你能举个例子吗? 我已经从这里http://blog.bignerdranch.com/463-a-motivation-for-ivar-decorations阅读了以下代码。
@property (copy) NSString *name;
...
@synthesize name;
...
- (void) setPonyInfoFromPropertyDict: (NSDictionary *) ponyProperties {
NSString *name = [ponyProperties objectForKey: @"Name"];
ponyName = name; //self.ponyName=name should solve the problem?
}
NSMutableString *mutableName = [NSMutableString stringWithString: @"Mikey"];
NSDictionary *ponyProperties = [NSDictionary dictionaryWithObject: mutableName
forKey: @"Name"];
[pony setPonyInfoFromPropertyDict: ponyProperties];
[mutableName setString: @"Wookiee"];
该代码和文章是否与此问题有关? 正确的方法是使用self.ponyName = name?在任何其他设置方法?
答案 0 :(得分:1)
我认为这个例子是错误的,或者是不合适的。一个恰当的例子应该是
@property (copy) NSString *ponyName; // not name!
...
@synthesize ponyName; // not name!
...
- (void) setPonyInfoFromPropertyDict: (NSDictionary *) ponyProperties {
NSString *name = [ponyProperties objectForKey: @"Name"];
ponyName = name;
//self.ponyName = name; // will solve the problem
}
name
可以是一个可变字符串,因此如果你想确保它在分配后不会改变,你必须复制它。您可以使用copy
属性执行该任务,但执行
ponyName = name;
你根本就没有使用过setter。
self.ponyName = name;
将解决问题,并且name
将被设置者复制。
在Objective-C中编程时最常见的错误之一是直接访问ivar而不是使用setter / getter。
附件方法非常重要,因为它们通常为访问和设置ivars提供了大量逻辑,最值得关注的是内存管理。如今,ARC编译器大大简化了它们的实现,但是,如果您使用MRC,附件方法对于帮助处理release
/ retain
平衡至关重要。
在ARC下仍然有效的示例是当您声明copy
属性时。在这种情况下,合成的setter会在分配到ivar之前复制参数,所以当你这样做时
[self setMyCopyProperty:aNewThing];
或等效
self.myCopyProperty = aNewThing;
在被分配到支持的ivar之前, aNewThing
会收到copy
消息。
另一方面,如果您合成这样的属性
@synthesize myCopyProperty;
你可能会意外地发现自己在做什么
myCopyProperty = aNewThing;
不会复制aNewThing
,因为您直接访问了ivar。
为了不混淆ivars和附属方法,然后将ivars加上下划线成为标准惯例,即将它们合成为
@synthesize myCopyProperty = _myCopyProperty;
这样,如果你不小心做了
myCopyProperty = aNewThing;
它不会编译,因为没有myCopyProperty
ivar这样的东西,在你调试与内存相关的问题时可能会让你免于头痛。如果您知道自己在做什么并且您真的想要访问ivar(可能是init
方法),那么您可以简单地执行
_myCopyProperty = [aNewThing copy];
更明确地说明了你不使用二传手的意图。
最后,值得注意的是,使用clang
编译器的现代版本,您可以避免使用显式@synthesize
,因为它将以
@synthesize foo = _foo;
有一些例外适用,您可以在此处详细了解:When should I use @synthesize explicitly?