【问题标题】:Using dot notation for instance methods对实例方法使用点表示法
【发布时间】:2011-06-15 21:21:16
【问题描述】:

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

例如:

@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”在不是结构或联合的东西中”。我错过了什么,知道吗?

【问题讨论】:

  • 这些是实例方法(以- 开头),而不是类方法(以+ 开头)。
  • @Jeremy 你是对的,我只是将措辞改为“实例”而不是“类”方法。他正在使用 self.instanceMethod 来访问该方法返回的值。如果编译器不抱怨,我无法在我的代码中复制它。
  • 在您向我们展示您在做什么之前,我们无法告诉您您缺少什么。

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


【解决方案1】:

点语法通常应用于声明的属性,但这不是强制性的。使用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]

【讨论】:

  • @Grady 并不是因为在一般情况下不需要取消引用指向 Objective-C 对象的指针,而且 valueAvalueB 不是结构成员。
  • 对我来说,我知道你是大师,但是 (*a).valueA 很好,a->valueA 很好,但不是 a.valueA。
  • @Grady (*a).valueA 如果 valueA 是一个结构成员(例如,一个 ivar,可能是一个公共的),那会很好,但它不是。而是一种方法。
  • @Grady,您将 C(也用于 C++)结构和指针语法与添加的 Objective-C 属性语法混淆了。如上所述,当您没有关于对象(指针)MyClass 的完整类型信息时,它只会看到id,因此会以structure or union 程序员熟悉的structure or union 措辞失败(因为它是在这一点上无效的 C)。当编译器知道类型时,它可以正确地将语法解析为应有的属性语法。
  • @Grady 那是因为它是点表示法,而不是属性表示法。 ;-) 你可以在没有声明属性的情况下使用它,尽管它不是很常见。
猜你喜欢
  • 2012-07-08
  • 2016-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多