3

I'm new to iOS development, currently following along with Lynda's tutorial by Simon Allardice on iOS SDK Essential Training, the chapter on "Creating quick connections."

I'm getting this error message on build:

"Use of undeclared identifier 'myTextfield'; Did you mean '_myTextfield'?"

The error message implicates this line of code:

- (IBAction)changeLabel:(id)sender
{
    NSString *message = [[NSString alloc] initWithFormat:@"Hello %@",   myTextfield.text];
}

The variable "myTextfield" (spelt correctly, and sans underscore) is clearly declared in the associated header file:

@property (weak, nonatomic) IBOutlet UITextField *myTextfield;

I'm confounded by the suggestion that I place an underscore in front of the var name. Nevertheless, if I follow this recommendation, the code compiles.

I'm using Xcode 4.6.3 with Lion on a MacBook Pro.

Can someone please suggest a solution to this mystery?

4

2 回答 2

3

属性与实例变量不同,您应该阅读一些内容,互联网上有很多资源。

总而言之,属性是实例变量(默认情况下,用下划线自动声明)和 get 和 set 方法的组合。

要访问您班级中的属性,您应该调用self.propertyName,在您的情况下它会是self.myTextfield。这将访问属性的gererated get 方法。当然,如果您在类中,您总是可以跳过 get 方法并直接访问变量。在这种情况下,它将是_myTextfield

如果您对生成的这个自动实例变量不满意,您始终可以声明自己的变量并使用@synthesize命令将其与属性绑定。像这样:

@synthesize myTextfieldProperty = myTextfieldVariable;

以下是有关synthesize. 正如我之前所说,此命令将一个 iVar 绑定到一个属性。因此,当您在类中执行上面的行时,您可以直接引用 iVar,调用myTextfieldVariable,或通过属性,self.myTextfieldProperty(实际上它们之间存在一些差异,但我没有详细输入)。

如果您不编写synthesize,那么 xcode 会自动为您执行以下操作:

@synthesize myTextfield = _myTextfield;

因此,在您的情况下,由于您没有合成您的属性,xcode 会在开头自动创建带有下划线的 iVar。这只是 xcode 遵循的模式。

该行@synthesize myTextfield;不直接绑定iVar,简单相同

@synthesize myTextfield = myTextfield;

即,您正在创建一个与您的财产同名的 iVar。为什么这两条线实际上是一回事?我不知道,这只是 xcode 遵循的一种模式。

希望这很清楚,英语不是我的母语。抱歉有任何错误。

于 2013-08-24T16:49:56.240 回答
1

属性是由 ivar 支持的 setter 和 getter 方法。创建隐式综合属性时,会使用前导下划线创建相应的 ivar。这是为了提醒您,您是直接直接访问 ivar 而不是通过属性。

这是因为属性为您负责内存管理,而直接 ivar 访问不在非 ARC 代码中。此外,属性会为您处理发布键值观察通知,如果您直接更改值,则需要自己处理 KVO 通知。此外,属性可能会覆盖 setter 或 getter 以产生副作用(例如,在视图上设置字符串时,将视图标记为需要再次绘制。)。直接访问不会触发这些副作用。

在您的 init 和 dealloc 方法中,您应该直接访问 ivar。通常所有其他访问都应通过 setter 和 getter 方法,例如[self setMyTextfield:]self.myTextfield

我觉得奇怪的一种行为是,如果您通过添加到您的实现文件中显式合成@synthesize myTextfield;您的属性,则创建的 ivar没有前导下划线。

有关属性、ivars 和 setter 方法的更多信息,请阅读Apple 关于此事的 Objective-C 文档

于 2013-08-24T16:56:55.900 回答