Frage

Im Grunde genommen habe ich die folgenden Code (hier erklärt: Objective-C Konstanten in Protokoll )

// MyProtocol.m
const NSString *MYPROTOCOL_SIZE;
const NSString *MYPROTOCOL_BOUNDS;

@implementation NSObject(initializeConstantVariables)

+(void) initialize {
     if (self == [NSObject class])
     {
         NSString **str = (NSString **)&MYPROTOCOL_SIZE;
         *str = [[MyClass someStringLoadedFromAFile] stringByAppendingString:@"size"];
         str = (NSString **)&MYPROTOCOL_BOUNDS;
         *str = [[MyClass someStringLoadedFromAFile] stringByAppendingString:@"bounds"];
     }
}

@end

Ich habe mich gefragt: Ist es sicher für mich, eine Kategorie zu haben, dass überschreibt die +initialize Methode des NSObject

?
War es hilfreich?

Lösung

Kurz gesagt, nein, man kann nicht sicher +initialize Methoden in Kategorien auf Klassen implementieren. Sie werden eine vorhandene Implementierung ersetzt am Ende, wenn es einen gibt, und wenn zwei Kategorien von einer Klasse sowohl +initialize implementieren, gibt es keine Garantie, die ausgeführt wird.

+load hat berechenbarer und Verhalten gut definiert, aber passiert, zu früh, etwas Sinnvolles zu tun, weil so viele Dinge in einem nicht initialisierten Zustand sind.

Persönlich überspringen I +load oder +initialize zusammen und verwenden Sie einen Compiler-Annotation eine Funktion zu veranlassen, auf Belastung des zugrunde liegenden binären / dylib ausgeführt werden. Dennoch gibt es sehr wenig ist man zu dieser Zeit sicher tun können.

__attribute__((constructor))
static void MySuperEarlyInitialization() {...}

Sie sind besser weit weg Ihre Initialisierung in Reaktion auf die Anwendung tun erzogen. NSApplication und UIApplication beide bieten Delegierten / notification Haken für so leitet sie ein Stück Code in der App zu injizieren.

Andere Tipps

Warum nicht Sie Setup diese beiden Variablen innerhalb der Klasse MyClass statt? Und auch, warum Sie nicht Accessoren benutzen? Statt eine gefälschte konstante Größe aufweist, die aus dem Nichts kommt, ist es vorzuziehen, einen Accessor für eine Klasse zu definieren, die es tatsächlich verwendet werden soll. Ein einfaches + (NSString *) myProtocolSize; täte toll, auch im Protokoll.

Auch zwingende Methoden einer Klasse in einer Kategorie „Werk“ ist aber nicht zuverlässig und sollte auf jeden Fall vermieden werden: Wenn die Methode, die Sie überschreiben sind in einer Kategorie durchgeführt wird, wird die Laufzeit nicht die Reihenfolge beim Laden garantieren und Ihre Implementierung vielleicht nie zu hinzugefügt werden.

Eine Variable vom Typ NSString *const immer, bevor Sie Ihr Code ausgeführt initialisiert wird, unter der Annahme, ignorieren wir C ++ Tücke für den Moment:

NSString *const MY_PROTOCOL_SIZE = @"...";

Eine Variable vom Typ const NSString * (das const Schlüsselwort zu den Eingeweiden der NSString Anwendung nicht seine Adresse) kann von jedem Code geändert werden, jedoch kann keine Nachrichten an sie gesendet hat. Es besiegt den Zweck, es const. Betrachten wir stattdessen eine globale Funktion:

static NSString *GetMyProtocolSize(void) {
    return [[MyClass someStringLoadedFromAFile] ...];
}

oder eine Klassenmethode verwendet werden:

@implementation MyClass
+ (NSString *)myProtocolSize {
    return [[MyClass someStringLoadedFromAFile] ...];
}
@end

Sie fragte eine Frage früher darüber, warum Ihr const Strings dynamische Werte nicht akzeptieren würde - das ist, weil Sie scheinen zu einem Symbol nicht zu verstehen, was const tut. Sie sollten über die Bedeutung des const Schlüsselwort in C lesen, und an einem anderen Ansatz aussehen sollte die Saiten zu bekommen, wenn const nicht das richtige ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top