2013-11-14 15 views
1

我已经阅读过有关这个问题的不同来源:书籍,文章等,但无法理解它。你能否举一个例子来说明支持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?在任何其他设置方法?

回答

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属性的任务,但你不使用的setter都做

ponyName = name; 

self.ponyName = name; 

将修复问题并且name将被设置者复制。


探讨

其中最常见的错误时在Objective-C的编程是访问的ivar直接代替使用设置器/吸气剂。

配件方法很重要,因为它们通常提供了很多访问和设置ivars的逻辑,最值得关注的是内存管理。现在,ARC编译器大大简化了它们的实现,但是,如果您使用MRC,配件方法对于帮助处理余额至关重要。

在ARC下仍然有效的示例是声明copy属性。在这种情况下,合成的二传会照顾参数复制的分配给伊娃之前,所以当你

[self setMyCopyProperty:aNewThing]; 

或等价

self.myCopyProperty = aNewThing; 

aNewThing将收到一个copy消息,被分配到前支持的伊娃。

在另一方面,如果你合成的属性这样

@synthesize myCopyProperty; 

你可能会意外地发现自己做

myCopyProperty = aNewThing; 

,不会复制aNewThing,因为你是直接访问伊娃。

为了不混淆ivars和配件方法,它成为一个标准约定,在ivars前加下划线,即综合他们像

@synthesize myCopyProperty = _myCopyProperty; 

这样,如果你不小心做

myCopyProperty = aNewThing; 

不能编译,因为作为一个myCopyProperty伊娃没有这样的事情,可能是从一个可怕的头痛节省你当你是调试内存相关的问题。相反,如果你知道自己在做什么,你真的要访问的伊娃(也许在init法),你可以简单地做

_myCopyProperty = [aNewThing copy]; 

这是很多你不使用二传手的意图更加明确。

最后,它可能是值得注意的是,与clang编译器的现代版本可以避开明确@synthesize,因为它会在

@synthesize foo = _foo; 

有些例外适用的形式自动插入,你可以阅读更多关于它在这里:When should I use @synthesize explicitly?

+0

谢谢,现在我明白,伊娃只是分配给可变的变种,这可以在将来改变。所以需要复制? 但是,支持的问题是什么?什么是“支持”? – user2553675

+0

'支持伊娃'只是简单地表明该物业为您提供的ivar,该物业的最后一个例子是'foo',并且由伊娃'_foo'支持。 –

相关问题