2014-04-22 3 views
0

J'ai appris plus sur Cocoa, Objective-C et Xcode en contribuant à un projet open-source (IPMenulet); le projet supportait à l'origine OS X 10.5. Dans ma hâte, il semble que j'ai ajouté des fonctionnalités utilisant des éléments SDK (NSJSONSerialization et la directive de compilation @autoreleasepool) qui ne sont pas pris en charge par l'ancien SDK. Maintenant, je suis en train de déterminer si tout ce que je peux faire pour restaurer un soutien pour 10,5Prise en charge de nouvelles fonctionnalités dans les anciennes versions de OS X SDK

Options:

  • NSJSONSerialization - Je suppose que je pourrais passer à JSONKit
  • @autoreleasepool {} -?
  • @properties - ajouter @synthesize Ivars

Questions:

  • est-il un moyen (directives du compilateur?) À utiliser les nouveaux éléments du SDK si le système d'exploitation prend en charge, le passage à l'élément plus si nécessaire ? si c'est le cas, est-il préférable de refactoriser la fonctionnalité dans les méthodes spécifiques à la version (par exemple getJSONlegacy, getJSON)?
  • serait-il préférable de marquer le projet d'origine comme une branche distincte (pour permettre de l'améliorer)?
+1

Le point des nouvelles fonctionnalités est de laisser derrière les systèmes d'exploitation plus âgés. Vous devez aller au plus bas dénominateur commun lors du rétroportage. Annule tout et recommence. Vous n'avez pas forcément besoin de dépendances pour tout remplacer. Les parseurs JSON sont triviaux à écrire, vous devez déjà connaître MRC, et la synthèse des propriétés est une caractéristique de clang, pas du système d'exploitation. – CodaFi

Répondre

1

Différentes fonctionnalités impliquent différents composants du système d'exploitation, qui définissent comment une fonctionnalité peut être utilisée dans plusieurs versions d'OS X. Voici ma classification approximative:

  • La fonctionnalité est complètement fournie par un framework. Par exemple, NSJSONSerialization est disponible dans Mac OS X 10.7+. Vous pouvez utiliser la même solution pour toutes les versions de système d'exploitation ou vérifier au moment de l'exécution si certaines fonctionnalités sont disponibles. Par exemple,

    if ([view respondsToSelector:@selector(setAcceptsTouchEvents:)]) 
        [view setAcceptsTouchEvents:YES]; 
    

    Plus de détails concernant le soutien de plusieurs kits de développement se trouvent dans SDK Compatibility Guide. Using SDK-Based Development.

  • La fonctionnalité est entièrement fournie par le compilateur. Par exemple, @autoreleasepool, littéraux.

  • La fonctionnalité est fournie par le compilateur et l'exécution. Par exemple, synthèse par défaut @property. Voir Objective-C Feature Availability Index pour plus de détails.

  • fonctionnalité qui dépend du SDK contre lequel une application est liée. Il s'agit plus de changements de comportement, un tel mécanisme est décrit dans la section Compatibilité descendante dans AppKit Release Notes.

Et maintenant, revenons à votre question. Il y a un mécanisme pour vérifier dans l'exécution si une fonctionnalité est disponible, assez souvent respondsToSelector: peut faire le travail. Je recommande d'exposer une seule méthode qui fonctionne sur toutes les versions du système d'exploitation. Et seulement à l'intérieur de cette méthode, des différences entre les versions d'OS sont présentes.Par exemple,

- (NSString *)base64EncodingForData:(NSData *)data { 
    NSParameterAssert(data); 
    if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) { 
     return [data base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength]; 
    } 
    else { 
     // Manual encoding using <Security/SecEncodeTransform.h> and kSecBase64Encoding. 
    } 
} 

Vous pouvez créer une branche de maintenance 1.1, effectuer tous les travaux en maître, et la fusion de la branche de maintenance que des corrections de bugs. Donc à partir de la branche maintenance, vous allez sortir 1.1.1 et partir de master 1.2. C'est une approche viable. Mais vous ne pouvez pas prendre en charge Mac OS X 10.5 indéfiniment, vous devez donc décider dans quelle version d'IPMenulet vous allez supprimer le support 10.5.

1

Dans la mesure où il aide à tous, la version classique:

@autoreleasepool { ... code ... } 

était la suivante:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

... code ... 

[pool drain]; 

drain est préférable à la release normale car elle alors tout fonctionne correctement avec (aussi maintenant déconseillé) OS X garbage collection. Mais cela compte comme une libération, donc il n'y a pas de fuite de mémoire et vous ne devriez pas également libérer.

+0

est le code ('' ... code ...) entre le '' init' et drain' marqué comme 'autorelease' sans avoir à faire un travail supplémentaire? – craig

+0

Non sans ARC; vous devez explicitement 'autorelease'. Les objets entreront dans 'pool' et seront complètement libérés quand ils seront drainés. Donc, tout ce que vous faites est d'essayer d'éviter les goulots d'étranglement de l'empreinte mémoire - tout comme avec @ autorelease. – Tommy

Questions connexes