访问属性方法和类字段之间的区别(Objective-C)

时间:2023-01-15 15:03:41

Assume that I have this piece of code:

假设我有这段代码:

@interface Foo : NSObject {
    Bar *bar;
}

@property (retain, nonatomic) Bar *bar;

@end

When using this field/property, is there any difference between lines:

使用此字段/属性时,行之间是否有任何区别:

[self.bar doStuff];

and

[bar doStuff];

?

When doing assignment, property method will perform correct retaining, but what about the read access to the property, as described above? Is there any difference?

在进行赋值时,属性方法将执行正确的保留,但如上所述,对属性的读访问权如何?有什么区别吗?

4 个解决方案

#1


13  

There is a big difference. [self.bar doStuff] is equivalent to [[self bar] doStuff]

有一个很大的不同。 [self.bar doStuff]相当于[[self bar] doStuff]

[bar doStuff] is equivalent to [self->bar doStuff]

[bar doStuff]相当于[self-> bar doStuff]

The former uses the accessor method, the latter just accesses the instance variable bar directly.

前者使用访问器方法,后者只是直接访问实例变量栏。

If you use the @synthesize directive on your bar property, the compiler will generate two methods for you:

如果在bar属性上使用@synthesize指令,编译器将为您生成两种方法:

- (void)setBar:(Bar*)b;
- (Bar*)bar;

Also note, that the compiler generated setter method is retaining your Bar instance as you told it in the @property declaration.

另请注意,编译器生成的setter方法保留了您在@property声明中告诉它的Bar实例。

#2


2  

Using the accessor self.bar is translated into a method call: [self bar]. The period syntax is just for looks. Accessing the member variable directly doesn't involve an extra function call, and is therefore slightly faster. It really only matters if you're accessing it within a loop, or in some process where that difference will add up. (On the iPhone) The setters created for properties also have some extra overhead for doing key value coding. A KVO notification is sent when you call "setBar:" or say "self.bar =" , so calling it over and over will result in a flood of notifications.

使用访问者self.bar转换为方法调用:[self bar]。句点语法仅适用于外观。直接访问成员变量不涉及额外的函数调用,因此稍快一些。它真的唯一的问题是你是在循环中访问它,还是在某些过程中,这种差异会加起来。 (在iPhone上)为属性创建的setter也有一些额外的开销来进行键值编码。当您调用“setBar:”或说“self.bar =”时会发送KVO通知,因此反复调用它会导致大量通知。

Jim is right, though - there's no functional difference between a nonatomic @property and a direct use of the variable in your code. Unless you're really concerned with the speed, using the property is probably your best bet.

但Jim是对的 - 非原子@property与代码中的变量直接使用之间没有功能差异。除非你真的关心速度,否则使用房产可能是你最好的选择。

#3


0  

A synthesized (or correctly hand-written) nonatomic accessor will be functionally equivalent to

合成的(或正确的手写)非原子访问器在功能上等同于

- (Bar *)bar
{
    return bar;
}

so there is no functional difference between your two examples.

所以你的两个例子之间没有功能差异。

However, outside of -dealloc or your initializers, consistently accessing the property via its accessor is a good idea.

但是,在-dealloc或您的初始化程序之外,始终通过其访问者访问该属性是个好主意。

#4


0  

If you assign value to your field with a convenient constructor of a Bar class, your Bar field will become a Zombie sooner than your Bar Property with Retain option, because reference count is not incremented by assigning to fields, and sometimes you run into "accessing deallocated objects" error.

如果使用Bar类的方便构造函数为字段赋值,则Bar字段将比具有Retain选项的Bar Property更快成为Zombie,因为引用计数不会通过分配字段而增加,有时您会遇到“访问”解除分配的对象“错误。

#1


13  

There is a big difference. [self.bar doStuff] is equivalent to [[self bar] doStuff]

有一个很大的不同。 [self.bar doStuff]相当于[[self bar] doStuff]

[bar doStuff] is equivalent to [self->bar doStuff]

[bar doStuff]相当于[self-> bar doStuff]

The former uses the accessor method, the latter just accesses the instance variable bar directly.

前者使用访问器方法,后者只是直接访问实例变量栏。

If you use the @synthesize directive on your bar property, the compiler will generate two methods for you:

如果在bar属性上使用@synthesize指令,编译器将为您生成两种方法:

- (void)setBar:(Bar*)b;
- (Bar*)bar;

Also note, that the compiler generated setter method is retaining your Bar instance as you told it in the @property declaration.

另请注意,编译器生成的setter方法保留了您在@property声明中告诉它的Bar实例。

#2


2  

Using the accessor self.bar is translated into a method call: [self bar]. The period syntax is just for looks. Accessing the member variable directly doesn't involve an extra function call, and is therefore slightly faster. It really only matters if you're accessing it within a loop, or in some process where that difference will add up. (On the iPhone) The setters created for properties also have some extra overhead for doing key value coding. A KVO notification is sent when you call "setBar:" or say "self.bar =" , so calling it over and over will result in a flood of notifications.

使用访问者self.bar转换为方法调用:[self bar]。句点语法仅适用于外观。直接访问成员变量不涉及额外的函数调用,因此稍快一些。它真的唯一的问题是你是在循环中访问它,还是在某些过程中,这种差异会加起来。 (在iPhone上)为属性创建的setter也有一些额外的开销来进行键值编码。当您调用“setBar:”或说“self.bar =”时会发送KVO通知,因此反复调用它会导致大量通知。

Jim is right, though - there's no functional difference between a nonatomic @property and a direct use of the variable in your code. Unless you're really concerned with the speed, using the property is probably your best bet.

但Jim是对的 - 非原子@property与代码中的变量直接使用之间没有功能差异。除非你真的关心速度,否则使用房产可能是你最好的选择。

#3


0  

A synthesized (or correctly hand-written) nonatomic accessor will be functionally equivalent to

合成的(或正确的手写)非原子访问器在功能上等同于

- (Bar *)bar
{
    return bar;
}

so there is no functional difference between your two examples.

所以你的两个例子之间没有功能差异。

However, outside of -dealloc or your initializers, consistently accessing the property via its accessor is a good idea.

但是,在-dealloc或您的初始化程序之外,始终通过其访问者访问该属性是个好主意。

#4


0  

If you assign value to your field with a convenient constructor of a Bar class, your Bar field will become a Zombie sooner than your Bar Property with Retain option, because reference count is not incremented by assigning to fields, and sometimes you run into "accessing deallocated objects" error.

如果使用Bar类的方便构造函数为字段赋值,则Bar字段将比具有Retain选项的Bar Property更快成为Zombie,因为引用计数不会通过分配字段而增加,有时您会遇到“访问”解除分配的对象“错误。