对实例方法使用点符号
我今天正在查看一段代码,注意到这个特定的编码器使用点符号来访问实例方法(这些方法不取值,只是返回值)。
例如:
@interface MyClass : NSObject { } -(double)add; @end @implementation MyClass -(double)valueA { return 3.0; } -(double)valueB { return 7.0; } -(double)add { return self.valueA + self.valueB; } @end
他这样做了他的代码和编译器没有抱怨,但是当我在我的代码尝试像上面的例子中,我得到以下错误:“请求成员”valueA“的东西不是结构或联合”。 我错过了什么,有什么想法?
点语法通常应用于声明的属性,但这不是强制性的。 使用obj.valueA
和obj.valueB
确实有效。
你得到的错误信息可能是由于对象没有明确的typesMyClass *
。 例如,以下工作:
MyClass *obj1 = [MyClass new]; NSLog(@"%f %f %f", obj1.valueA, obj1.valueB, [obj1 add]);
另一方面:
MyClass *obj1 = [MyClass new]; NSLog(@"%f %f %f", obj1.valueA, obj1.valueB, [obj1 add]); id obj2 = obj1; NSLog(@"%f %f %f", obj2.valueA, obj2.valueB, [obj2 add]);
得到:
error: request for member 'valueA' in something not a structure or union error: request for member 'valueB' in something not a structure or union
因为obj2
具有typesid
,所以编译器没有足够的信息来知道.valueA
和.valueB
实际上是getter方法-valueA
和-valueB
。 如果将types为MyClass
对象放置在NSArray
,稍后通过-objectAtIndex:
检索它们, -objectAtIndex:
发生这种情况,因为此方法返回types为id
的通用对象。
为了安抚编译器,您需要将该对象转换为MyClass *
,然后才使用点语法。 你可以做到这一点:
MyClass *obj2 = obj1; // or MyClass *obj2 = [someArray objectAtIndex:someIndex]; // and then obj2.valueA
或者,如果obj2
被声明为id
:
((MyClass *)obj2).valueA
或者,如果该对象由返回types为id
的方法返回:
((MyClass *)[someArray objectAtIndex:someIndex]).valueA
或者,你可以完全摆脱点语法(我最喜欢的):
[obj2 valueA] [[someArray objectAtIndex:someIndex] valueA]