Reputation: 2331
I'm using a 3rd party class that contain the following extention:
@interface BaseClass ()
{
int privateMember;
}
@end
i've created my own subclass:
@interface SubClass : BaseClass {
}
@end
is there a way to access privateMember in SubClass?
EDIT: actual code
GPUImageMovie.m: (base class)
@interface GPUImageMovie ()
{
BOOL audioEncodingIsFinished, videoEncodingIsFinished;
GPUImageMovieWriter *synchronizedMovieWriter;
CVOpenGLESTextureCacheRef coreVideoTextureCache;
AVAssetReader *reader;
}
MultiTrackGPUImageMovie.h (subclass)
@interface MultiTrackGPUImageMovie : GPUImageMovie {
}
...
@end
MultiTrackGPUImageMovie.m (subclass)
- (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);
...
}
give error Use of undeclared identifier 'coreVideoTextureCache'
Upvotes: 3
Views: 2131
Reputation: 12446
For me it is impossible to use the default @protected ivar from the class extension in the subclass like said the the accepted answer, when the class extension is in the .m
file.
So here is how I could solve this issue without using the runtime API (which should not be used in such a manner).
They are implemented, also for the subclass `SubClass. You can not access them, because the declaration ist not visible to the subclass.
The subclass does not have access to the class extension @interface BaseClass ()
of the BaseClass
.
You have 2 options:
Copy
@interface BaseClass () { int privateMember; } @end
to every subclass. Yes it is the class extension of the BaseClass
inside the .m
file of the SubClass
.
OR
Create a .h
file without a .m
, only with the class extension code (like above) inside. Import that to the BaseClass
and the SubClass
.
Upvotes: 0
Reputation:
It depends on how the 'private' member has been declared. If there wasn't the @private
keyword before it, i. e. it was really
@interface BaseClass ()
{
int privateMember;
}
@end
and not
@interface BaseClass ()
{
@private
int privateMember;
}
@end
then you can easily reference this instance variable simply by using its name - the default access scope for instance variables is protected, i. e. not accessible outside the class, but accessible from subclasses.
However, if it was declared as private
, you'll have to fall back using the runtime functions; in your subclass, declare and implement this method:
- (void *)pointerForIvarWithName:(NSString *)name
{
Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
return ((char *)self) + ivar_getOffset(ivar);
}
Then use it like this:
int ivarPtr;
ivarPtr = *(int *)[self pointerForIvarWithName:@"privateMember"];
Edit: so it seems the member you're trying to access is in a class extension and not public in the header file. In this case, you can go for the 2nd solution only (although it's not advised to do so).
Upvotes: 5