2011-02-03 83 views
5

任何人都可以解释设置someObject = someOtherObject;self.someObject = someOtherObject;之间的区别,如果someObject是使用@property(nonatomic,retain)创建的类属性SomeType someObject;何时访问属性和自己什么时候?

为了澄清我有类似:

@interface SomeClass : NSObject { 
    SomeType* someObject; 
} 

@property (nonatomic, retain) SomeType* someObject; 

@end 

我已经注意到,我得到EXC_BAD ACCESS有时当我使用没有自我的财产,它似乎很随意。当我使用自己的时候,我的程序就像它应该那样行事。当我跳过自我时,我没有收到任何编译器错误或警告,所以我猜它是某种有效的语法?

+0

[我应该何时应该使用self关键字。](http://stackoverflow.com/questions/4080523/when-should-i-use-the-self-keyword)可能有重复,你在问这个问题之前搜索? – zoul 2011-02-03 09:34:27

回答

2

属性只是一种访问数据的便捷方式。所以当你声明属性@property(nonatomic,retain)SomeType * someObject;这意味着访问期间,存在将被合成的2种方法:

吸气剂:

-(SomeType*) someObject { 
    return someObject; 
} 

设定器

-(void) setSomeObject:(SomeType*) obj { 
    [someObject release]; 
    someObject = [obj retain]; 
} 

所以特性和实例变量之间的主要区别在于,属性动态地创建的setter /吸气剂方法(你可以覆盖它们)。但是当你写someObject = new_val时,你只是将引用复制到内存位置。除了一个汇编指令外,没有额外的工作完成。

还有一件事要提到:原子和非原子。 对于原子,合成的setter/getter将确保整个值总是从getter返回或由setter设置,而不管任何其他线程上的setter活动。也就是说,如果线程A位于获取者的中间,而线程B调用setter,则实际可行值(最有可能的自动释放对象)将返回给调用者A.

在非原子中,没有这样的保证。因此,非原子比原子快得多。

编辑:如果你有一些变量,可以从不同的线程访问或/和一些额外的工作必须完成(例如保留,提高一些标志......),那么你的选择是财产。但是有时你有一个变量,经常访问,通过属性访问可能会导致很大的开销,因为处理器必须执行更多的操作来合成和调用方法。

4

self.someObject = someOtherObject使用该属性。属性为你生成setter和getters。在你的情况下,你给属性retain属性,这意味着通过此属性设置的对象将自动收到一条retain消息,它将其保留计数增加1.此外,成员变量的旧值将发送release消息这减少了其保留数量。

如果您尝试访问解除分配的对象(例如,如果您尝试释放它太频繁),则系统会取消分配其中的Obects。如果您尝试访问解除分配的对象,则会获得EXC_BAD_ACCESS ecxeption。

你的情况:

SomeOtherObject *soo = [[SomeOtherObject alloc] init]; //retain count: 1 
self.someObject = soo; //soo's retain count is now 2 
[soo release]; //soo's retain count is 1 again, as self still uses it. 
[self doSomethingWithSoo]; 

但是,如果你不使用的setter,你不能释放soo

SomeOtherObject *soo = [[SomeOtherObject alloc] init]; //retain count: 1 
someObject = soo; //soo's retain count is still 1 
[soo release]; //soo's retain count is 0, it will be deallocated 
[self doSomethingWithSoo]; //will fail with an EXC_BAD_ACCESS exception, as soo does not exist anymore. 
0

两者之间的区别是:

1)当你不使用 “自我”。您将结果直接分配给成员变量。

2)当你使用“自我”。你正在调用该属性的setter方法。它与[self setMyObject:...]相同;

所以在self.myobject的情况下,它保留其保留,并在其他情况下,(没有自己),如果你不使用alloc,那么它将被视为自动释放对象。

在大多数情况下,您会发现要使用“self”,除了在对象初始化期间。

顺便问一下,你也可以使用self.someObject = [someOtherObject retain]增加保留柜台

1

这是所有关于内存管理。

您的班级资产someObject已在您的.h/.m文件中生成带注释@property/@synthsize的访问者。

当您使用someObject访问您的房产时,您可以直接访问该房产。当您访问self.someObject时,您打电话给您的访问者[self someObject],为您处理内存管理。

所以,当你需要分配一个类属性时,它会更清洁,因为你使用setter,并且不必关心释放和保留。当你的制作者使用@property (nonatomic, retain)生成时,所以它会照顾你。

相关问题