Antworten:
Sie können eine Methode weder als geschützt noch als privat deklarieren . Die Dynamik von Objective-C macht es unmöglich, Zugriffskontrollen für Methoden zu implementieren. (Sie können dies tun, indem Sie den Compiler oder die Laufzeit mit einer schwerwiegenden Geschwindigkeitsstrafe stark ändern, dies wird jedoch aus offensichtlichen Gründen nicht durchgeführt.)
Entnommen aus der Quelle .
Sie können den geschützten und privaten Zugriff auf Methoden folgendermaßen simulieren :
Diese Schutzmaßnahmen werden, wie Sachin feststellte, zur Laufzeit nicht durchgesetzt (wie dies beispielsweise in Java der Fall ist).
UIGestureRecognizerSubclass.h
Folgendes habe ich getan, um geschützte Methoden für meine Unterklassen sichtbar zu machen, ohne dass sie die Methoden selbst implementieren müssen. Dies bedeutete, dass ich in meiner Unterklasse keine Compiler-Warnungen über eine unvollständige Implementierung erhielt.
SuperClassProtectedMethods.h (Protokolldatei):
@protocol SuperClassProtectedMethods <NSObject>
- (void) protectMethod:(NSObject *)foo;
@end
@interface SuperClass (ProtectedMethods) < SuperClassProtectedMethods >
@end
SuperClass.m: (Der Compiler zwingt Sie jetzt, geschützte Methoden hinzuzufügen.)
#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.
performSelector
darauf.
[(id)obj hiddenMethod]
. Genau genommen wird die geschützte Methode in Objective-C nicht unterstützt.
Ich habe dies gerade entdeckt und es funktioniert für mich. Um Adams Antwort zu verbessern, führen Sie in Ihrer Oberklasse eine Implementierung der geschützten Methode in der .m-Datei durch, deklarieren Sie sie jedoch nicht in der .h-Datei. Erstellen Sie in Ihrer Unterklasse eine neue Kategorie in Ihrer .m-Datei mit der Deklaration der geschützten Methode der Oberklasse, und Sie können die geschützte Methode der Oberklasse in Ihrer Unterklasse verwenden. Dies verhindert letztendlich nicht, dass der Aufrufer der angeblich geschützten Methode zur Laufzeit gezwungen wird.
/////// 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
Eine andere Möglichkeit, @protected-Variablen zu verwenden.
@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
Sie können die Methode als private Methode der übergeordneten Klasse definieren und [super performSelector:@selector(privateMethod)];
in der untergeordneten Klasse verwenden.
Sie können eine Art dies mit einer Kategorie.
@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
Die Methoden werden nicht ausgeblendet, wenn Sie die Kategorie in eine andere Klasse importieren, aber Sie tun es einfach nicht. Aufgrund der Dynamik von Objective-C ist es tatsächlich unmöglich, eine Methode unabhängig von einem aufrufenden Instanztyp vollständig auszublenden.
Der beste Weg ist wahrscheinlich die von @Brian Westphal beantwortete Klassenfortsetzungskategorie, aber Sie müssen die Methode in dieser Kategorie für jede untergeordnete Instanz neu definieren.
Eine Möglichkeit besteht darin, die Klassenerweiterung zum Ausblenden von Methoden zu verwenden.
In .h
:
@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
In .m
:
@interface SomeAppDelegate()
- (void)localMethod;
@end
@implementation SomeAppDelegate
- (void)localMethod
{
}
@end
@interface
Deklaration in der .m-Datei brauchen. Sie können einfach eine Funktion deklarieren und verwenden, und sie wird als privat behandelt.