Защищенные методы в Objective-C - PullRequest
       0

Защищенные методы в Objective-C

110 голосов
/ 16 сентября 2010

Что эквивалентно защищенным методам в Objective-C? Я хочу определить методы, которые могут вызывать / реализовывать только производные классы.

Ответы [ 8 ]

155 голосов
/ 24 мая 2011

Вы можете имитировать защищенный и частный доступ к методам, выполнив следующие действия:

  • Объявите ваши закрытые методы в расширении класса (т.е. безымянная категория, объявленная в верхней части файла класса .m)
  • Объявите ваши защищенные методы в заголовке подкласса - Apple использует этот шаблон относительно UIGestureRecognizer (см. Документацию и ссылку на UIGestureRecognizerSubclass.h)

Как отметил Сачин, эти средства защиты не применяются во время выполнения (как, например, в Java).

46 голосов
/ 16 сентября 2010

Вы не можете объявить защищенный метод или закрытым. Динамическая природа Objective-C делает невозможным реализацию контроля доступа для методов. (Вы могли бы сделать это сильно изменение компилятора или среды выполнения, с серьезными потерями в скорости, но по понятным причинам этого не делается.)

Взято из Источник .

12 голосов
/ 01 октября 2012

Вот что я сделал, чтобы сделать защищенные методы видимыми для моих подклассов, не требуя от них реализации самих методов. Это означало, что я не получил предупреждения компилятора в моем подклассе о неполной реализации.

SuperClassProtectedMethods.h (файл протокола):

@protocol SuperClassProtectedMethods <NSObject>
- (void) protectMethod:(NSObject *)foo;
@end

@interface SuperClass (ProtectedMethods) < SuperClassProtectedMethods >
@end

SuperClass.m: (теперь компилятор заставит вас добавлять защищенные методы)

#import "SuperClassProtectedMethods.h"
@implementation SuperClass
- (void) protectedMethod:(NSObject *)foo {}
@end

SubClass.m:

#import "SuperClassProtectedMethods.h"
// Subclass can now call the protected methods, but no external classes importing .h files will be able to see the protected methods.
9 голосов
/ 03 января 2014

Я только что обнаружил, и это работает для меня. Чтобы улучшить ответ Адама, в своем суперклассе сделайте реализацию защищенного метода в файле .m, но не объявляйте его в файле .h. В вашем подклассе создайте новую категорию в вашем файле .m с объявлением защищенного метода суперкласса, и вы можете использовать защищенный метод суперкласса в своем подклассе. Это в конечном итоге не предотвратит вызов метода, который предположительно защищен, если его принудительно выполнить во время выполнения.

/////// SuperClass.h
@interface SuperClass

@end

/////// SuperClass.m
@implementation SuperClass
- (void) protectedMethod
{}
@end

/////// SubClass.h
@interface SubClass : SuperClass
@end

/////// SubClass.m
@interface SubClass (Protected)
- (void) protectedMethod ;
@end

@implementation SubClass
- (void) callerOfProtectedMethod
{
  [self protectedMethod] ; // this will not generate warning
} 
@end
2 голосов
/ 12 сентября 2014

Другой способ использования @защищенных переменных.

@interface SuperClass:NSObject{
  @protected
    SEL protectedMehodSelector;
}

- (void) hackIt;
@end

@implementation SuperClass

-(id)init{

self = [super init];
if(self) {
 protectedMethodSelector = @selector(baseHandling);
 }

return self;
}

- (void) baseHandling {

  // execute your code here
}

-(void) hackIt {

  [self performSelector: protectedMethodSelector];
}

@end

@interface SubClass:SuperClass
@end

@implementation SubClass

-(id)init{

self = [super init];
if(self) {
 protectedMethodSelector = @selector(customHandling);
 }

return self;
}

- (void) customHandling {

  // execute your custom code here
}

@end
1 голос
/ 27 марта 2013

Вы можете определить метод как закрытый метод родительского класса и использовать [super performSelector:@selector(privateMethod)]; в дочернем классе.

0 голосов
/ 20 ноября 2013

Вы можете вроде сделать это с категорией.

@interface SomeClass (Protected)
-(void)doMadProtectedThings;
@end

@implementation SomeClass (Protected)

- (void)doMadProtectedThings{
    NSLog(@"As long as the .h isn't imported into a class of completely different family, these methods will never be seen. You have to import this header into the subclasses of the super instance though.");
}

@end

Методы не будут скрыты, если вы импортируете категорию в другой класс, но вы просто этого не сделаете. Из-за динамической природы Objective-C фактически невозможно полностью скрыть метод независимо от типа вызывающего экземпляра.

Наилучший путь - это, вероятно, категория продолжения класса в ответе @Brian Westphal, но вам придется переопределить метод в этой категории для каждого подкласса.

0 голосов
/ 29 июня 2012

Один из вариантов - использовать расширение класса для скрытия методов.

В .h:

@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

В .m:

@interface SomeAppDelegate()
- (void)localMethod;
@end

@implementation SomeAppDelegate

- (void)localMethod
{
}

@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...