未声明的标识符,建议插入下划线。工作,但为什么?

时间:2013-08-24 16:39:40

标签: ios objective-c identifier

我是iOS开发的新手,目前正在跟随Simon Allardice关于iOS SDK Essential Training的Lynda教程,即“创建快速连接”一章。

我在构建时收到此错误消息:

  

“使用未声明的标识符'myTextfield';您的意思是'_myTextfield'吗?”

错误消息暗示了这行代码:

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

变量“myTextfield”(拼写正确,sans下划线)在关联的头文件中明确声明:

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

我对在var名称前放置下划线的建议感到困惑。不过,如果我遵循这个建议,代码就会编译。

我在MacBook Pro上使用Xcode 4.6.3和Lion。

有人可以建议解决这个谜团吗?

2 个答案:

答案 0 :(得分: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遵循的模式。

直接绑定iVar的行@synthesize myTextfield;

相同
@synthesize myTextfield = myTextfield;

即。您正在创建一个与您的财产名称相同的iVar。为什么这两条线在行为上是一样的呢?我不知道,这只是xcode遵循的模式。

希望这很清楚,英语不是我的母语。对不起任何错误。

答案 1 :(得分:1)

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

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

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

我发现奇怪的一个行为是,如果您通过将<{1}}添加到您的实现文件中来明确合成您的属性,则创建的ivar 具有领先的下划线。

有关属性,ivars和setter方法的更多信息,请阅读Apple's Objective-C documentation on the matter