何时在类属性上使用self?

4th*_*ace 7 objective-c

类属性何时需要?例如:

self.MyProperty = @"hi there";
Run Code Online (Sandbox Code Playgroud)

VS

MyProperty = @"hi there";
Run Code Online (Sandbox Code Playgroud)

MyProperty是一个NSString设置为(非原子,副本).上述两种内存管理有什么不同吗?

什么时候没有属性,并且在头文件中声明了变量MyProperty?如果从未在类之外引用,是否需要属性?它对内存管理有所影响吗?

nes*_*nce 8

是的,内存和性能都有所不同.

MyProperty = @"hi there";
Run Code Online (Sandbox Code Playgroud)

这被认为是直接分配.实际上没有内存或性能影响.当然,这并不是说这是最佳实践 - 这是一个不同的问题:)

@property(nonatomic, copy) NSString *MyProperty;
// ...
self.MyProperty = @"hi there";
Run Code Online (Sandbox Code Playgroud)

此声明对内存和性能有重大影响.这基本上相当于:

-(void)setMyProperty(NSString *)newValue {
    if (MyProperty != newValue) {
        [MyProperty release];
        MyProperty = [newValue copy];
    }
}
Run Code Online (Sandbox Code Playgroud)

旧值将被释放,新值将复制到MyProperty中.这是可以接受的,尤其是当你的分配字符串可变时处理字符串时(例如,它可能会在以后更改).

如果在你的例子中,你只是简单地指定一个静态字符串(@"hi there"),那么直接分配字符串值没有错; 它的效率更高,但性能上的差异是微不足道的.

您可以将@property的属性声明为retain,copy或assign(默认为assign).然后,您可以使用@synthesize生成"访问者"(getter/setter)方法.以下是执行此操作时生成的setter方法的外观:

// @property(nonatomic, assign)
-(void)setMyProperty(NSString *)newValue {
    MyProperty = newValue;
}

// @property(nonatomic, retain)
-(void)setMyProperty(NSString *)newValue {
    if (property != newValue) {
        [property release];
        property = [newValue retain];
    }

// @property(nonatomic, copy)
-(void)setMyProperty(NSString *)newValue {
    if (property != newValue) {
        [property release];
        property = [newValue copy];
    }
}
Run Code Online (Sandbox Code Playgroud)

有关ObjectiveC声明的属性的更多信息.

"您可以在@implementation块中使用@synthesize和@dynamic指令来触发特定的编译器操作.请注意,任何给定的@property声明都不需要.

要点:如果没有为特定属性指定@synthesize或@dynamic,则必须为该属性提供getter和setter(或者只是readonly属性的getter)方法实现."

换句话说,如果声明属性但不合成属性,除非定义"MyProperty"和"setMyProperty"方法,否则将无法使用[self MyProperty]或self.MyProperty.如果您没有声明属性,那么您只需要一个实例变量.

注意:@dynamic不会生成访问者.如果你通过加载代码或动态方法解析动态地(即,神奇地)解析访问器方法,它就真的被使用了.

  • 您描述的"影响"与内存或性能无关.因此我注意到的不良做法是一个不同的问题;)您的评论不正确.在这个问题中,属性是NSString,所有赋值都是常量 - @"hi there"是一个NSString常量,而不是一个对象.如果编写一个将值设置为@"a string"的应用程序,无论是通过赋值,复制还是保留,该变量将始终指向内存中的相同地址空间.属性用于公开实例变量,而不是内存管理或寻址. (3认同)

smo*_*gan 7

不同之处在于

self.MyProperty = @"hi there"
Run Code Online (Sandbox Code Playgroud)

是点符号调用,它将调用生成的访问器,它将正确处理保留计数(相当于[self setMyProperty:@"hi there"]),而

MyProperty = @"hi there"
Run Code Online (Sandbox Code Playgroud)

是对您的成员变量的直接赋值,它不会释放旧值,保留新值或执行您的访问者所做的任何其他操作(例如,如果您有自定义setter执行额外工作).

所以,是的,内存管理和两者之间的行为存在很大差异.后一种形式几乎总是错误的,除非您明确知道为什么要这样做并且您自己正确处理保留计数.