对实例方法使用点符号

我今天正在查看一段代码,注意到这个特定的编码器使用点符号来访问实例方法(这些方法不取值,只是返回值)。

例如:

@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.valueAobj.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]