我是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。
有人可以建议解决这个谜团吗?
答案 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