Как мы скрываем закрытый класс при использовании его в Objective-C? - PullRequest
0 голосов
/ 18 января 2019

Вопрос

Как скрыть закрытый класс при использовании его в Objective-C?

Например, как описано ниже PrivateFilter это класс, который я хочу скрыть. CustomFilter это класс, который я делаю, который открыт. GPUImageFilter это класс public на Github, который тоже открыт. И CustomFilter фактически включает функциональность PrivateFilter.

@interface CustomFilter : GPUImageFilter
@end

@interface PrivateFilter : GPUImageFilter
@end

Возможные решения

Итак, есть два решения:

Решение 1: кластер классов

Посмотрите на пример A Composite Object: An Example в документе Apple . Я следовал за шагами и сделал следующий код.

// 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

Но почему-то это не работает, поэтому я пробую решение 2.

Решение 2. Инициирование с PrivateFilter

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

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

@end

Это работает, но очень странно использовать alloc в init. Поэтому я пробую решение 3.

Решение 3: метод фабричного класса

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

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

@end

Это работает, но не может быть унаследовано, как кластер классов.

Повторите вопрос

ТАК какое лучшее решение? Или есть другие хорошие решения?

1 Ответ

0 голосов
/ 18 января 2019

Я думаю, вам нужен протокол вместо CustomFilter с заводским подходом. Если вам нужен подкласс GPUImageFilter, вы можете сделать 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

При таком подходе Xcode даже выдаст вам предупреждения, если вы забудете реализовать некоторые методы.

...