Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

Ответ 3

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

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.

Ответ 4

Я только что открыл это, и он работает для меня. Чтобы улучшить ответ Адама, в вашем суперклассе сделайте реализацию защищенного метода в файле .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

Ответ 5

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

Ответ 6

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

@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

Ответ 7

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

В .h:

@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

В .m:

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

@implementation SomeAppDelegate

- (void)localMethod
{
}

@end

Ответ 8

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

@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, но вам придется переопределить метод в этой категории для каждого подкласса.