3

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

@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'

4

2 回答 2

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"];

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

于 2012-08-04T18:39:02.897 回答
0

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

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


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

子类 无权访问@interface BaseClass ().BaseClass

您有 2 个选项:

复制

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

到每个子类。是的,是.BaseClass.mSubClass

或者

创建一个.h没有 的文件.m,只在里面包含类扩展代码(如上)。将其导入到BaseClassSubClass

于 2014-05-20T19:09:06.013 回答