访问子类中的private(类扩展)成员

时间:2012-08-04 18:31:12

标签: objective-c

我正在使用包含以下扩展名的第三方类:

@interface BaseClass ()
{
   int privateMember;
}
@end

我创建了自己的子类:

  @interface SubClass : BaseClass {
  }
  @end

有没有办法在SubClass中访问privateMember?


编辑: 实际代码

GPUImageMovie.m :(基类)

@interface GPUImageMovie ()
{
    BOOL audioEncodingIsFinished, videoEncodingIsFinished;
    GPUImageMovieWriter *synchronizedMovieWriter;
    CVOpenGLESTextureCacheRef coreVideoTextureCache;
    AVAssetReader *reader;
}

MultiTrackGPUImageMovie.h(子类)

@interface MultiTrackGPUImageMovie : GPUImageMovie {
}
...
@end

MultiTrackGPUImageMovie.m(子类)

 - (void)processMovieFrame:(CMSampleBufferRef)movieSampleBuffer forTarget:(int)targetToSendIdx {
 ...
 CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,       coreVideoTextureCache, movieFrame, NULL, GL_TEXTURE_2D, GL_RGBA, bufferWidth, bufferHeight,   GL_BGRA, GL_UNSIGNED_BYTE, 0, &texture);
 ...
}

给出错误  使用未声明的标识符'coreVideoTextureCache'

2 个答案:

答案 0 :(得分:5)

这取决于私人'会员已被宣布。如果不是之前的@private关键字,我。即真的是

@interface BaseClass ()
{
    int privateMember;
}
@end

@interface BaseClass ()
{
    @private
    int privateMember;
}
@end

然后您可以通过使用其名称轻松引用此实例变量 - 实例变量的默认访问范围受到保护,即。即不能在课外访问,但可以从子类访问。

但是,如果 声明为private,则您必须使用运行时函数退回;在你的子类中,声明并实现这个方法:

- (void *)pointerForIvarWithName:(NSString *)name
{
    Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
    return ((char *)self) + ivar_getOffset(ivar);
}

然后像这样使用它:

int ivarPtr;
ivarPtr = *(int *)[self pointerForIvarWithName:@"privateMember"];

编辑:所以您尝试访问的成员似乎是在类扩展中,而不是在头文件中公开。在这种情况下,您只能使用第二种解决方案(尽管不建议这样做)。

答案 1 :(得分:0)

对我来说,不可能使用子类中类扩展的默认@protected ivar,如接受的答案,当类扩展名在.m文件时。

所以这就是我如何在不使用运行时API的情况下解决这个问题(不应该以这种方式使用)。


它们也被实现,也用于子类`SubClass。您无法访问它们,因为声明对子类不可见。

子类无法访问@interface BaseClass ()类扩展 BaseClass

您有两个选择:

复制

@interface BaseClass () {
    int privateMember;
}
@end

到每个子类。是的,它是BaseClass .m文件中SubClass类扩展名

创建一个没有.h的{​​{1}}文件,只有里面有类扩展代码(如上所述)。将其导入.mBaseClass