2009-08-11 37 views
9

有没有一种方法可以在不隐藏变量的情况下为与Objective-C中的实例变量同名的方法提供参数?参数隐藏Objective-C中的实例变量

例如,

- (void)doSomething:(id)object 
{ 
    self.object = object; 
}

上面的代码给出警告“‘对象’的本地声明隐藏实例变量。”

显而易见的解决方案是以不同的方式命名参数参数,但是我觉得烦恼不得不选择“anObject”而不是“object”这样的名称。

+1

当你说“局部变量”时,我认为你的意思是“实例变量”。参数是一种局部变量。 – outis 2009-08-11 02:57:50

+0

谢谢outis。我纠正了这个问题。 – titaniumdecoy 2009-08-11 03:13:42

回答

8

您可以使用点符号来访问属性(如您在示例中所做的那样),但实例变量只有一个访问路径,所以如果您想要访问实例变量和局部变量,唯一的解决方法是给他们不同的名字。

从形式上讲,这与lambda演算中alpha conversion的限制有关,具体来说,绑定变量应该保持绑定状态,并且自由变量保持空闲状态。

如果您不喜欢本地语言的“an”前缀,则可以对实例变量使用“_”前缀约定,因为它们也是有效保护的变量。

@interface AClass { 
    id _object; 
} 
@property (retain) id object; 
@end 

@implementation AClass 
@synthesize object = _object; 

- (void)doSomething:(id)object 
{ 
    [_object befriend:object]; 
} 
... 

当然,“_”读为“我的”,所以它可能与参数前的“a”/“an”一样令人讨厌。重命名是最好的解决方案,因为实例和局部变量有不同的角色,他们的名字应该反映这一点。

+2

其实,你可以通过self> object来访问ivars。此外,苹果公司“保留”自己使用的下划线前缀,尽管似乎没有人注意到这一点。就我个人而言,我使用i_作为我的ivars的前缀,这也有助于将它们与属性区分开来。 – 2009-08-11 04:32:23

+0

添加下划线还可以区分'_object = something'和'self.object = something',这两个完全不同的代码位。 – kubi 2009-08-11 15:19:08

+0

如果所讨论的方法实际上是实例变量的setter,该怎么办?有什么不同? – Tony 2011-12-08 07:02:31

13

您可能可以执行类似self->object = object的操作,但Objective-C约定(派生自Smalltalk)是在参数名称与实例变量名称相同的情况下,使用“a”或“an”作为参数前缀。

+2

+1这个答案。公共Cocoa API使用参数名称,如“anObject”和“aDictionary”来区分实例变量。除了遵循惯例之外,这使得不太可能偶然地提及错误的变量,并且更容易重构。 – 2009-08-11 03:30:48

+0

这是Apple推荐的解决方案,再加上它是一个很好的惯例,IMO。 “ - (void)doSomething:(id)anObject”。 – andyvn22 2009-08-11 16:39:39