参考文章https://www.devtalking.com/articles/you-should-to-know-property/
property是声明属性的语法,可以快速方便的为实例变量创建存取器,减少程序员的代码量,使代码更加整洁。
方便的创建存取器
在.h文件中,我们使用@property声明了name和damage两个属性,与实例变量名称相同
@interface Sword : NSObject{
NSString *name;
int damage;
}
@property NSString *name;
@property int damage;
@end
在.m文件中,使用@synthesize表明编译器自动生成这两个变量的存取器,生成getter和setter函数,在iOS6之后LLVM编译器 引入了property autosynthesis(属性自动合成),也就是说,编译器会自动为每一个@property添加@synthesis
@implementation Sword
@synthesize name;
@synthesize damage;
@end
通过上述的声明,我们可以使用点或者消息的方式调用name和damage
Sword *sword = [[Sword alloc] init];
sword.name = @"霜之哀伤";
[sword setDamage:999];
省去单独声明实例变量
在上面的代码中,如果使用@property声明了属性,系统会自动生成实例变量,默认的实例变量名称为在属性名前加下划线。
下面的代码和前面的代码效果相同,不同的是系统自动生成的实例变量为_name和_damage,同时在.m文件中,编译器会自动使用@synthesize声明语句
@interface Sword : NSObject
@property NSString *name;
@property int damage;
@end
若希望修改编译器自动生成的实例对象名称,可以在.m文件中写
@synthesize name = sword_name;
总结:在头文件中,仅需要使用@property进行属性声明,即可同时生成实例变量和对应的存取器,若对实例对象的名称有要求,可手动使用@synthesize来指定生成的实例对象名称
property的特性
在属性声明的时候,添加不同的特性,编译器根据特性来实现getter和setter方法。
- assign:简单赋值,适用于基本数据类型
- copy:创建一个新对象,新对象和旧对象是两个独立的对象
- retain:在赋值过程中,引用计数加1
- strong:强引用,表示实例对象对传入的对象有所有权关系,引用计数加1
- weak:在setter方法中,对传入的对象不进行引用加1的操作,当该对象引用计数为0时,使用weak声明的实例对象指向nil,通常delegate和Outlet使用weak来声明。
- readonly和readwrite:属性默认为readwrite,即生成getter和setter方法,readonly表示只生成getter方法,可以通过setter=myGetter表示希望编译器生成的存取器的名称
- atomic和nonatomic:atomic表示操作是原子性的,意味着只有一个线程访问实例变量,但会影响效率,nonatomic是非原子的,效率比atomic快,但不能保证在多线程环境下的安全性,默认情况下,实例变量为atomic,所以一般使用需要手动声明nonatomic特性。