Zdefiniowanie prywatnych metod w @implementation
bloku jest idealne do większości celów. Clang zobaczy je w @implementation
, niezależnie od kolejności deklaracji. Nie ma potrzeby deklarowania ich w kontynuacji klasy (aka rozszerzenie klasy) lub kategorii nazwanej.
W niektórych przypadkach będziesz musiał zadeklarować metodę w kontynuacji klasy (np. Jeśli używasz selektora między kontynuacją klasy a @implementation
).
static
funkcje są bardzo dobre dla szczególnie wrażliwych lub krytycznych pod względem szybkości prywatnych metod.
Konwencja nazywania prefiksów może pomóc ci uniknąć przypadkowego zastąpienia metod prywatnych (uważam, że nazwa klasy jest bezpieczna dla prefiksu).
Nazwane kategorie (np. @interface MONObject (PrivateStuff)
) Nie są szczególnie dobrym pomysłem ze względu na potencjalne kolizje nazw podczas ładowania. Są one naprawdę przydatne tylko w przypadku metod przyjacielskich lub chronionych (które bardzo rzadko są dobrym wyborem). Aby upewnić się, że jesteś ostrzegany przed niekompletnymi implementacjami kategorii, powinieneś to zaimplementować:
@implementation MONObject (PrivateStuff)
...HERE...
@end
Oto mała ściągawka z adnotacjami:
MONObject.h
@interface MONObject : NSObject
// public declaration required for clients' visibility/use.
@property (nonatomic, assign, readwrite) bool publicBool;
// public declaration required for clients' visibility/use.
- (void)publicMethod;
@end
MONObject.m
@interface MONObject ()
@property (nonatomic, assign, readwrite) bool privateBool;
// you can use a convention where the class name prefix is reserved
// for private methods this can reduce accidental overriding:
- (void)MONObject_privateMethod;
@end
// The potentially good thing about functions is that they are truly
// inaccessible; They may not be overridden, accidentally used,
// looked up via the objc runtime, and will often be eliminated from
// backtraces. Unlike methods, they can also be inlined. If unused
// (e.g. diagnostic omitted in release) or every use is inlined,
// they may be removed from the binary:
static void PrivateMethod(MONObject * pObject) {
pObject.privateBool = true;
}
@implementation MONObject
{
bool anIvar;
}
static void AnotherPrivateMethod(MONObject * pObject) {
if (0 == pObject) {
assert(0 && "invalid parameter");
return;
}
// if declared in the @implementation scope, you *could* access the
// private ivars directly (although you should rarely do this):
pObject->anIvar = true;
}
- (void)publicMethod
{
// declared below -- but clang can see its declaration in this
// translation:
[self privateMethod];
}
// no declaration required.
- (void)privateMethod
{
}
- (void)MONObject_privateMethod
{
}
@end
Inne podejście, które może nie być oczywiste: typ C ++ może być zarówno bardzo szybki, jak i zapewniać znacznie wyższy stopień kontroli, minimalizując jednocześnie liczbę eksportowanych i ładowanych metod objc.