2012-08-14 23 views
5

Mountain Lion ha introdotto new APIs, alcune delle quali sono state implementate come categorie nel nostro progetto.Categorie condizionali in Mountain Lion

Per esempi, abbiamo una categoria NSColor+CGColorAdditions che ha implementato CGColor e colorWithCGColor: per NSColor. Questi metodi sono stati aggiunti a Mountain Lion.

Idealmente, vorremmo utilizzare queste categorie se il sistema operativo client è più vecchio di Mountain Lion e non usarlo se si tratta di Mountain Lion. Come possiamo farlo? O c'è un'alternativa migliore?

risposta

7
NSColor *_NSColor_colorWithCGColor_(Class self, SEL cmd, CGColorRef cgColor) 
{ 
    // make an NSColor outta `cgColor` and return it 
    return nsColor; 
} 

// inside some initialization code 

if ([[NSColor class] respondsToSelector:@selector(colorWithCGColor:)]) { 
    // on ML, don't do anything 
} else { 
    // older system, add your own category 
    class_addMethod(objc_getMetaClass("NSColor"), @selector(colorWithCGColor:), (IMP)_NSColor_colorWithCGColor_, "@@:@"); 
} 
+0

Grazie. Dove consiglieresti di inserire questo codice di inizializzazione? Può essere eseguito staticamente all'interno di -say- il file di categoria? – hpique

+0

@hgpc forse tra le primissime linee dell'applicazione: didFinishLaunchingWithOptions: method. –

+1

Davvero? Lo metterei in un metodo di caricamento +. –

2

Ho pensato che potrebbe anche essere utile postare ciò che ho fatto in base alla risposta di H2CO3.

NSColor+CGColorAdditions.m divennero:

static CGColorRef _NSColor_CGColor_(Class self, SEL cmd) { 
    return nil; // TODO: Do something 
} 

static NSColor* _NSColor_colorWithCGColor_(Class self, SEL cmd, CGColorRef aColor) { 
    return nil; // TODO: Do something  
} 

__attribute__((constructor)) 
static void initialize_NSColor_CGColorAdditions() { 
    if (![[NSColor class] respondsToSelector:@selector(colorWithCGColor:)]) { 
     class_addMethod(objc_getMetaClass("NSColor"), @selector(colorWithCGColor:), (IMP)_NSColor_colorWithCGColor_, "@@:@"); 
    } 
    if (![[NSColor class] instancesRespondToSelector:@selector(CGColor)]) { 
     class_addMethod(objc_getClass("NSColor"), @selector(CGColor), (IMP)_NSColor_CGColor_, "@@:"); 
    } 
} 
+0

Non sono sicuro di voler usare 'constructor' per questo, perché non è chiaro quando verrà chiamato in relazione al runtime che si sta configurando. A ['+ load'] (http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/doc/uid/20000050- caricare) il metodo di categoria è probabilmente il luogo appropriato per farlo. –

+0

@ W'rkncacnter Per quanto ne so, le funzioni di costruzione sono chiamate prima di main. –

+1

@ H2CO3: Giusto - la mia preoccupazione è che vengano chiamati prima che il runtime sia stato costruito, ma non sono esattamente sicuro quando ciò accadrà. È logico che sia quando viene caricato libobjc, quindi probabilmente non è un problema, ma '+ load' _is_ esplicitamente per giocare con le classi prima di main. –

Problemi correlati