如何从iOS类获得_CAEAGLNativeWindow" CAEAGLLayer"

时间:2014-11-03 02:32:44

标签: ios objective-c

我试图从类中获取OpenGL ES本机窗口(_win):

@interface CAEAGLLayer : CALayer <EAGLDrawable>
{
@private
  struct _CAEAGLNativeWindow *_win;
}

所以我用类别扩展了它:

@interface CAEAGLLayer(MyLayer)
- (void*) fetchWin;
@end

@implementation CAEAGLLayer(MyLayer)
- (void*) fetchWin
{
    return self->_win;
}
@end

并在另一个班级中使用它:

@implementation MyClass
- (void)setupLayer
{
    _eaglLayer = (CAEAGLLayer*)self.layer;
    _eaglLayer.opaque = YES;
    NSLog(@"_eaglLayer _win: %p", [_eaglLayer fetchWin]);
}
@end 

但是在构建时遇到了链接错误:

Undefined symbols for architecture x86_64:
  "_OBJC_IVAR_$_CAEAGLLayer._win", referenced from:
      -[CAEAGLLayer(MyLayer) fetchWin] in OpenGLView.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

1 个答案:

答案 0 :(得分:1)

链接器找不到符号,因为默认情况下,“@private@package ivars are not exported的ivar符号”。因此,即使您有一个引用它的标题,您也无法以这种方式直接通过名称访问_win

但是,您可以深入了解ObjC运行时并提取实例变量。在您的情况下,您可以在-setupLayer(#importing <objc/objc-runtime.h>之后)尝试类似的内容:

Ivar winIvar = class_getInstanceVariable([CAEAGLLayer class], "_win");
void * winptr = (__bridge void *)object_getIvar(_eaglLayer, winIvar);

(您也可以使用-valueForKey:作为密钥的名称在图层上使用简单的@"_win",但我更喜欢运行时方法,因为他们会更清楚地了解您正在尝试的内容要做,这基本上绕过了预期的抽象。)