How do we hide private class when using it in Objective-C?

104 Views Asked by At

Question

How do we hide private class when using it in Objective-C?

For example, as described below PrivateFilter is the class I want to hide. CustomFilter is the class I make, which is open. GPUImageFilter is the class public on Github, which is open, too. And CustomFilter actully wraps the functionallity of PrivateFilter.

@interface CustomFilter : GPUImageFilter
@end

@interface PrivateFilter : GPUImageFilter
@end

Possible Solutions

So there are two solutions:

Solution 1: Class cluster

Have a look at the example A Composite Object: An Example in the Apple document. I followed the steps and make the following code.

// CustomFilter.h
@interface CustomFilter : GPUImageFilter
@end

// CustomFilter.m
@interface CustomFilter()
@property (nonatomic, strong) PrivateFilter *privateFilter;
@end

@implementation CustomFilter
- (instancetype)init
{
    self = [super init];
    if (self) {
        _privateFilter = [[PrivateFilter alloc] init];
    }
    return self;
}

// and then override the most of GPUImageFilter functions...
@end

But somehow it doesn't work, so I try the solution 2.

Solution 2: Init with PrivateFilter

// CustomFilter.h
@interface CustomFilter : GPUImageFilter
@end

// CustomFilter.m
@implementation CustomFilter
- (CustomFilter *)init
{
    self = (CustomFilter *)[[PrivateFilter alloc] init];
    return self;
}

@end

This works, but it's very strange to use alloc in init. So I try the solution 3.

Solution 3: factory class method

// CustomFilter.h
@interface CustomFilter : GPUImageFilter
+ (CustomFilter *)filter;
@end

// CustomFilter.m
@implementation CustomFilter
+ (CustomFilter *)filter
{
    CustomFilter *filter = (CustomFilter *)[[PrivateFilter alloc] init];
    return filter;
}

@end

This works, but it could not be inherited, just like class cluster.

Repeat Question

SO which is the best solution? Or is there other some good solutions?

1

There are 1 best solutions below

2
On

I think you need protocol, instead of CustomFilter with factory approach. If you need some GPUImageFilter subclass you can make GPUImageFilter<CustomFilter>

//CustomFilter.h
@protocol CustomFilter

...

@end

typedef GPUImageFilter<CustomFilter> CustomFilter;

//PrivateFilter.h
#import "CustomFilter.h"
@interface PrivateFitler: CustomFilter
...
@end

//GPUImageFilter+CustomFilter.h
@interface GPUImageFilter(CustomFilter)

+ (CustomFilter *)filter;

@end

//GPUImageFilter+CustomFilter.m
#import "PrivateFilter.h"

@implementation GPUImageFilter(CustomFilter)

+ (CustomFilter *)filter
{
    return [[PrivateFilter alloc] init;
}
@end

With such approach Xcode even give you warnings if you forget to implement some methods.