Xcode 4.5在自动生成属性及其相关内存释放部分(在dealloc和viewDidUnload中)的方式是否略有不同
我昨天从4.5 Beta 1升级到了Xcode 4.5。现在,当我使用Interface Builder创建出口时(通过Ctrl从UILabel拖动到相关的头文件),它会在头中正常创建@property
声明:
@property (retain, nonatomic) IBOutlet UILabel *propertyName;
但是,在关联的.m文件中,没有@synthesize
声明。
viewDidUnload
中的代码正常:
- (void)viewDidUnload {
[self setPropertyName:nil];
[super viewDidUnload];
}
但是,dealloc
中的代码在属性名称上预加了一个_
- (void)dealloc {
[_propertyName release];
[super dealloc];
}
这也意味着我不能将属性引用为正常([propertyName doSomething];
)
有什么变化吗?还是我不小心巧合地改变了一些设置?
是的,Xcode 4.5中的行为略有变化。
。。。在关联的.m文件中,没有@synthesis声明。
在Xcode 4.5中,@synthesize
语句现在是可选的,并且会自动合成属性。因此,自动生成的IBOutlet属性不再添加@synthesize
,因为它不再是必需的。
。。。dealloc中的代码在属性名上加上一个_
当自动合成属性时(没有显式的@synthesis语句),相应的实例变量以下划线开头。这就是为什么它在dealloc方法中显示为这样的原因。这样实例变量和属性名称就不会重叠。
这也意味着我不能将属性引用为正常
否。访问实例变量和属性没有更改。所更改的只是实例变量的默认名称。例如:
_foo = @"Bar"; // Setting an instance variable directly.
self.foo = @"Bar"; // Setting an instance variable via a property accessor method.
下划线只是一个样式问题,因此更清楚地表明您访问的是实例变量而不是属性。
请注意,您可以自己添加@synthesis语句,这将强制相应实例变量的名称为您希望的名称。同样,如果您添加自己的属性访问器方法,则将阻止自动生成实例变量。
Xcode现在自动将所有属性合成为一个名为_propertyName
的实例变量。在许多情况下,您不再需要@synthesize
或显式声明实例变量。
对于XCode 4.5,现在默认情况是将下划线添加到底层实例变量中。但这对您的唯一影响是,您需要用下划线引用该变量。这里有一个例子:
@property (retain) UIColor color;
在您的实现代码中,您可以参考如下颜色:
[_color set]; // Now do some drawing...
对外界来说,一切都没有改变。
object.color = [UIColor redColor];
此更改基于一种常见做法,即使用下划线前缀命名实例变量,以将它们与代码中的局部变量区分开来。
此外,请注意,您通常希望以[self.propertyName doSomething];
的形式访问您的属性,这就是为什么在实例变量前自动加下划线以表示隐私是有意义的。
如果你真的必须这样做,如果你让它自动合成,你可以把它作为[_propertyName doSomething]
访问,但这会绕过getter。或者,你可以@synthesize propertyName = propertyName;
再次使用[propertyName doSomething]
,但你为什么要这样做?
我发现,如果在@property名称之前使用下划线,您就可以像以前一样实现所需的方法。