pic*_*ick 5 iphone objective-c self ios
任何人都可以解释设置之间的区别someObject = someOtherObject;,self.someObject = someOtherObject;如果someObject是用@property创建的类属性(非原子,保留)SomeType someObject;
澄清我有类似的东西:
@interface SomeClass : NSObject {
SomeType* someObject;
}
@property (nonatomic, retain) SomeType* someObject;
@end
Run Code Online (Sandbox Code Playgroud)
我注意到,当我使用没有自己的属性时,我有时会得到EXC_BAD ACCESS,而且看起来很随机.当我使用self时,我的程序应该是应有的.当我跳过self时,我没有得到任何编译器错误或警告,所以我猜它是某种有效的语法?
self.someObject = someOtherObject利用酒店.属性为您生成setter和getter.在您的情况下,您将retain属性赋予属性,这意味着通过此属性设置的对象将自动接收一条retain消息,该消息将其保留计数增加1.此外,成员变量的旧值将发送一条release消息,该消息会减少其保留计数.
当保留计数达到0时,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];
Run Code Online (Sandbox Code Playgroud)
但是,如果您不使用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.
Run Code Online (Sandbox Code Playgroud)
属性只是访问数据的一种便捷方式。因此,当您声明属性 @property (nonatomic, keep) SomeType* someObject; 时 这意味着在访问期间将合成 2 个方法:
吸气剂:
-(SomeType*) someObject {
return someObject;
}
Run Code Online (Sandbox Code Playgroud)
二传手
-(void) setSomeObject:(SomeType*) obj {
[someObject release];
someObject = [obj retain];
}
Run Code Online (Sandbox Code Playgroud)
因此,属性和 ivars 之间的主要区别在于属性动态创建 setter/getter 方法(并且您可以覆盖它们)。但是当您编写 someObject = new_val 时,您只是将引用复制到内存位置。除了一条汇编指令外,没有进行任何其他工作。
还有一件事要提:原子和非原子。使用原子,合成的 setter/getter 将确保始终从 getter 返回整个值或由 setter 设置整个值,而不管任何其他线程上的 setter 活动如何。也就是说,如果线程 A 位于 getter 中间,而线程 B 调用 setter,则实际可行的值(很可能是自动释放的对象)将返回给 A 中的调用者。
在非原子中,没有做出这样的保证。因此,非原子比原子要快得多。
编辑:所以如果你有一些变量,可以从不同的线程访问或/并且必须完成一些额外的工作(例如保留,引发一些标志......),那么你的选择就是属性。但有时您有一个经常访问的变量,并且通过属性访问可能会导致很大的开销,因为处理器必须执行更多操作来合成和调用方法。