Xcode 4.5 Interface Builder将Undercore添加到Outlets



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名称之前使用下划线,您就可以像以前一样实现所需的方法。

最新更新