我正在使用包含以下扩展名的第三方类:
@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'
答案 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}}文件,只有里面有类扩展代码(如上所述)。将其导入.m
和BaseClass
。