8

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];)

有什么改变吗?还是我不小心更改了某些设置?

4

5 回答 5

14

是的,Xcode 4.5 中的行为略有改变。

...在关联的 .m 文件中,没有 @synthesize 声明。

在 Xcode 4.5 中,该@synthesize语句现在是可选的,并且属性是自动合成的。自动生成的 IBOutlet 属性因此不再添加@synthesize,因为不再需要它。

... dealloc 中的代码在属性名称前添加了一个 _

当属性被自动合成(没有显式的 @synthesize 语句)时,相应的实例变量会在前面加上下划线。这就是为什么它在您的 dealloc 方法中如此显示的原因。这样实例变量和属性名称就不会重叠。

这也意味着我无法正常引用该属性

没有。访问实例变量和属性没有改变。改变的只是实例变量的默认名称。例如:

_foo = @"Bar"; // Setting an instance variable directly.
self.foo = @"Bar";  // Setting an instance variable via a property accessor method.

下划线只是样式问题,因此更清楚的是您访问的是实例变量而不是属性。

请注意,您可以自己添加 @synthesize 语句,这将强制相应实例变量的名称为您想要的任何名称。同样,如果您添加自己的属性访问器方法,那么这将阻止实例变量自动生成。

于 2012-09-23T05:56:03.597 回答
3

Xcode 现在自动将所有属性合成为一个名为_propertyName. 在许多情况下,您不再需要@synthesize或显式声明实例变量。

于 2012-09-23T05:23:45.140 回答
2

在 XCode 4.5 中,默认情况下现在将下划线添加到底层实例变量。但这对您的唯一影响是您需要使用下划线引用该变量。这是一个例子:

@property (retain) UIColor color;

在您的实现代码中,您可以像这样引用颜色:

[_color set]; // Now do some drawing...

对于外部世界来说,事情保持不变。

object.color = [UIColor redColor];

此更改基于一种常见做法,即使用下划线前缀命名实例变量,以将它们与代码中的局部变量区分开来。

于 2012-09-23T05:27:30.747 回答
0

另外,请注意,您通常希望以 访问您的属性[self.propertyName doSomething];,这就是为什么使用下划线自动为实例变量添加前缀以指示隐私是有意义的。

如果你真的需要,你可以像[_propertyName doSomething]让它自动合成一样访问它,但这会绕过 getter。或者,您可以再次@synthesize propertyName = propertyName;使用[propertyName doSomething],但您为什么要这样做?

于 2012-09-23T05:29:13.813 回答
-1

我发现,如果您在 @property 名称前使用下划线,您就可以像以前一样实现所需的方法。

于 2012-09-23T05:27:22.053 回答