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

s20*_*der 3 iphone objective-c key-value-coding ios

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

例如:

@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
Run Code Online (Sandbox Code Playgroud)

他通过他的代码完成了这个并且编译器没有抱怨,但是当我在我的代码中尝试它时,如上面的例子我得到以下错误:"请求成员"valueA"在某个结构或联合的东西中".我想念的是什么?

小智 7

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

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

MyClass *obj1 = [MyClass new];
NSLog(@"%f %f %f", obj1.valueA, obj1.valueB, [obj1 add]);
Run Code Online (Sandbox Code Playgroud)

另一方面:

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]);
Run Code Online (Sandbox Code Playgroud)

得到:

error: request for member ‘valueA’ in something not a structure or union
error: request for member ‘valueB’ in something not a structure or union
Run Code Online (Sandbox Code Playgroud)

因为obj2有类型id,所以编译器没有足够的信息来知道它.valueA并且.valueB实际上是getter方法-valueA-valueB.如果您将类型的对象MyClass放在an中NSArray并稍后通过它检索它-objectAtIndex:,则会发生这种情况,因为此方法返回类型的通用对象id.

要安抚编译器,您需要将对象强制转换为MyClass *仅使用点语法.你可以通过以下方式完成

MyClass *obj2 = obj1;
// or
MyClass *obj2 = [someArray objectAtIndex:someIndex];
// and then
obj2.valueA
Run Code Online (Sandbox Code Playgroud)

或者,如果obj2声明为id:

((MyClass *)obj2).valueA
Run Code Online (Sandbox Code Playgroud)

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

((MyClass *)[someArray objectAtIndex:someIndex]).valueA
Run Code Online (Sandbox Code Playgroud)

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

[obj2 valueA]
[[someArray objectAtIndex:someIndex] valueA]
Run Code Online (Sandbox Code Playgroud)