Ответы:
Вы не можете объявить метод защищенным или частным. Динамический характер Objective-C делает невозможным реализацию контроля доступа для методов. (Вы можете сделать это, сильно изменив компилятор или среду выполнения, со значительным снижением скорости, но по очевидным причинам этого не происходит.)
Взято из источника .
Вы можете смоделировать защищенный и частный доступ к методам, выполнив следующие действия:
Эти средства защиты, как заметил Сачин, не применяются во время выполнения (как, например, в Java).
UIGestureRecognizerSubclass.h
Вот что я сделал, чтобы сделать защищенные методы видимыми для моих подклассов, не требуя от них реализации самих методов. Это означало, что я не получал предупреждений компилятора в моем подклассе о неполной реализации.
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
Подкласс.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.
performSelector
это сделать.
[(id)obj hiddenMethod]
. Точно говоря, защищенный метод не поддерживается в Objective-C.
Я только что обнаружил это, и это работает для меня. Чтобы улучшить ответ Адама, в вашем суперклассе создайте реализацию защищенного метода в файле .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
protectedMethod
Другой способ использования @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
Вы можете определить метод как частный метод родительского класса и использовать его [super performSelector:@selector(privateMethod)];
в дочернем классе.
Вы можете вид сделать это с категорией.
@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, но вам придется переопределить метод в этой категории для каждого экземпляра подкласса.
Один из вариантов - использовать расширение класса, чтобы скрыть методы.
В .h
:
@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
В .m
:
@interface SomeAppDelegate()
- (void)localMethod;
@end
@implementation SomeAppDelegate
- (void)localMethod
{
}
@end
@interface
объявление в .m файле. Вы можете просто объявить функцию и использовать ее, и она будет рассматриваться как закрытая.