Відповіді:
Ви не можете оголосити метод захищеним або приватним. Динамічний характер 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
Ви можете сортувати це за допомогою категорії.
@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. Ви можете просто оголосити функцію та використовувати її, і вона буде вважатись приватною.