【问题标题】:objective c xcode 4.0.2: subclass can't access superclass variables "was not declared in this scope"目标c xcode 4.0.2:子类无法访问超类变量“未在此范围内声明”
【发布时间】:2011-06-18 09:08:14
【问题描述】:

我有几个类是一个 Layer 类的子类。由于某种原因,其中一个子类的行为不同。这是一个精简版:

@interface Layer: CCLayer
{
 GameScene* _scene;
 CCNode* _layerNode;
}
@end

#import "Layer.h"
@interface UILayer: Layer
{
}
@end

@implementation UILayer
-(void) doStuff
{
  [_layerNode addChild:[CCNode node]];  <---gives compile error: "_layerNode was not declared in this scope"
  [_scene playSound];<------gives compile error: "_scene was not declared in this scope"
}
@end

我认为这可以理解基本概念。我可以通过这样做来解决这个问题

[[_self _layerNode] addChild:[CCNode node]];
[[_self _scene] playSound];

但我想不通的是为什么Layer的其他子类可以直接访问_layerNode和_scene?我猜这是构建设置的问题。此外,仅当我为设备(iphone)而不是模拟器构建它时才会发生此问题。如果您需要更多信息来回答,请告诉我。

编辑:

哎呀,我写错了。它应该是[[self _layerNode] addNode:[CCNode node]],但我想问题是为什么一个子类可以直接访问 ivar _layerNode 而另一个必须使用[self _layerNode] 访问它。就像UILayer找不到超类头

【问题讨论】:

  • 您要么需要发布真实代码,要么发布一个在编译时会导致问题的最小示例。如所写,(a)该代码应该可以正常编译,但(b)_self 没有意义。如上所述,这听起来像是一个潜在的编译器错误。

标签: iphone objective-c xcode inheritance scope


【解决方案1】:

来自文档:Apple Objective-C Programming Language(不再提及,但您可以在 this retired document 中找到它)

实例变量可以在声明它的类和继承它的类中访问。所有没有显式作用域指令的实例变量都有@protected 作用域。

但是,可以在任何地方访问公共实例变量,就好像它是 C 结构中的字段一样。例如:

Worker *ceo = [[Worker alloc] init];

ceo-&gt;boss = nil;

我使用 LLVM GCC 4.2 时出现编译错误(对于 iOS 项目,在设备上):

error: 'fooInstanceVar' undeclared (第一次在这个函数中使用) 和使用 GCC 4.2 的相同: 错误:“fooInstanceVar”未声明(在此函数中首次使用)

我可以使用LLVM Compiler 2.0 编译而不会出错。

使用LLVM GCC 4.2GCC 4.2 编译,使用self-&gt;

[NSArray arrayWithObjects:self.barProperty, self-&gt;fooInstanceVar, nil];doSomethingWithProperty 方法中。

【讨论】:

    【解决方案2】:

    也许是名字。 'UI' 前缀是为 UIKit 类指定的。很可能 UILayer 是 Apple 使用的私有 UIKit 类。

    【讨论】:

      【解决方案3】:

      如果您@synthesize ivars,编译器会毫无帮助地阻止您“直接”访问它们。修复相对简单:写self-&gt;_layerNodeself-&gt;_scene

      我假设您的“精简版”编译良好。

      请注意,除非您了解其实现细节,否则直接访问您的 superlcas 的 ivars 也是一种不好的形式。

      _self 是什么?)

      【讨论】:

      • @bbum:他不需要;如果 UILayer 合成了 ivars(它可能;代码是“精简的”),在 GCC 4.2 中,如果你不使用 self-&gt;,它似乎会破坏对超类 ivars 的访问
      • 我可以相信 GCC。该编译器已过时,不应使用(除了仍然依赖 GCC-isms 的罕见 C++ 部分)。这个特定的错误已经在 LLVM 中修复了很长时间。
      • @bbum:也许苹果出于各种原因正在转向 LLVM,但我不会称 GCC 本身“过时”;令人失望的是 GCC 4.4 不受支持(直到 iPhoneOS 3 才支持 GCC 4.2)。
      • 是的——我应该更准确些。 4.2 已过时,不再维护。至于 4.4 —— 并没有过时,但 GPL v3 似乎限制了商业领域的采用。
      猜你喜欢
      • 2016-09-18
      • 2017-02-12
      • 1970-01-01
      • 2017-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多