声明了@property
并@synthesize
后编译器会为你的实例变量生成getter和setter,这些方法会遵循你声明的内存管理的语义,在set的时候执行对应的操作,比如retain
,copy
等;但它们是方法,而不是变量,所以obj.foo
= @"a"
其实是一个语法糖,等同于[obj
setFoo:@"a"]
。在过去你还需要声明对应的实例变量,并通过@synthesize foo =
_foo
的方式建立和它们之间的关系,但新的Clang编译器会默认帮你加入@synthesize
的步骤,默认实例变量形式为property名加下划线。但是你依然可以声明实例变量,并手动建立和property的关系,尤其是实例变量的形式与默认的不同,比如:@synthesize
foo = _bar
。
一般的情况下你应该多用@property,因为它可以进行某种程度的自动内存管理(根据你声明时的语意义),但是由于getter和setter本质上是普通的方法,所以它们可以被覆盖,可以执行除了get和set额外的操作(副作用),所以在某些情况下(比如init...和dealloc方法里)你会手动去进行赋值。
同理,由于@property声明的是方法,你可以不必有对应的实例变量,而是自行实现一个getter和setter执行自定义的操作。有时候你甚至不用去声明对应的实例变量和getter/setter,因为它们在父类已经存在,或者在运行时才存在,那么这时候你会用到@dynamic
而不是@synthesize
,不然编译器会报错。
关于使用实例变量还是@property,其实和用不用ARC没有太多关系。。。,它们也不是互相替代的关系