使用点表示法作为实例方法

时间:2011-06-15 21:21:16

标签: iphone objective-c ios key-value-coding

我今天看了一段代码并注意到这个特定的编码器使用点符号来访问实例方法(这些方法不接受值,它们只返回值)。

例如:

@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“在某些东西不是结构或联合”。我想念的是什么,任何想法?

1 个答案:

答案 0 :(得分:7)

点语法通常应用于声明的属性,但这不是必需的。使用obj.valueAobj.valueB确实有效。

您获得的错误消息可能是由于对象没有明确的类型MyClass *。例如,以下工作:

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的类型为id,所以编译器没有足够的信息知道.valueA.valueB实际上是getter方法-valueA-valueB。如果您将MyClass类型的对象放在NSArray中,然后通过-objectAtIndex:检索它们,就会发生这种情况,因为此方法会返回id类型的通用对象。

要安抚编译器,您需要将对象强制转换为MyClass *,然后才使用点语法。你可以通过以下方式实现这一目标:

MyClass *obj2 = obj1;
// or
MyClass *obj2 = [someArray objectAtIndex:someIndex];
// and then
obj2.valueA

或,如果obj2被声明为id

((MyClass *)obj2).valueA

或者,如果对象是由返回类型为id的方法返回的:

((MyClass *)[someArray objectAtIndex:someIndex]).valueA

或者,你可以完全摆脱点语法(我最喜欢的):

[obj2 valueA]
[[someArray objectAtIndex:someIndex] valueA]