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

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

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

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

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

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

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

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

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

 @protocol SuperClassProtectedMethods  - (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. 

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

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

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

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

 @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 

Вы можете сделать это с помощью категории.

 @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 

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

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

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

В .h :

 @interface SomeAppDelegate : UIResponder  @property (strong, nonatomic) UIWindow *window; @end 

В .m :

 @interface SomeAppDelegate() - (void)localMethod; @end @implementation SomeAppDelegate - (void)localMethod { } @end 
  • Отправка сообщения в ноль в Objective-C
  • Есть ли разница между «переменной экземпляра» и «свойством» в Objective-c?
  • Что такое быстрый математический анализатор C или Objective-C?
  • Как я могу вызвать метод в Objective-C?
  • Чтение данных из файла Excel в Objective-C (iPhone)
  • Как преобразовать int в NSString?
  • Как передать значения по ссылке в объекте C (iphone)
  • (objective C) В чем преимущество использования @synthesize myvar = _myvar (если есть)?
  • Как я могу создать базовый UIButton программно?
  • Динамические свойства Objective-C во время выполнения?
  • Объектные переменные экземпляра C
  • Давайте будем гением компьютера.