Cacao et tactile ont évidemment beaucoup de choses en commun. Ils utilisent le même langage sous-jacente, elles utilisent toutes deux classes de la Fondation, et ils ont tous deux suivi de nombreux modèles de conception identique. Le fait qu'ils sont conçus pour fonctionner à différents types de matériel physique et le fait que Cocoa Touch a été créé près de vingt ans après le cacao (n'ee NexSTEP), signifie qu'il ya certains domaines qui sont très différents. Ces différences peuvent vous jeter, car beaucoup de choses entre les deux est le même.
La plus évidente de ces différences est que le concept de classes de contrôleur générique de vue est «cuit dans" à Cocoa Touch, mais ont été ajoutés au cacao, après qu'il a été autour depuis des années. Mais c'est un sujet pour un blog affichage distinct. Aujourd'hui, je veux parler de l'autre, la différence un peu plus subtile, qui est que le Touch Cacao et mettre en œuvre les délégués de manières complètement différentes. Regardons les objets déléguer plus couramment utilisées: les délégués d'application. Les deux cadres d'application des délégués-UIApplicationDelegate et NSApplicationDelegate-servir le même but, mais sont mises en oeuvre différemment.
Delegation n'est pas unique à l'Objective-C. C'est un modèle reconnu qui est utilisé dans de nombreuses langues, mais avec parcimonie dans la plupart des. En raison de l'Objective-C dynamique, la nature faiblement typé, la pomme et des ingénieurs de NeXT a réalisé très tôt que la délégation a souvent été un meilleur choix que l'héritage, ce qui explique pourquoi la hiérarchie de classes pour le cacao et Cocoa Touch est généralement plus plat que les hiérarchies de l'orienté objet cadres d'application intégré dans d'autres langues. Si vous venez à Objective-C récemment d'un autre langage OO, chaque fois que votre premier réflexe est de sous-classe, prendre du recul et demandez-vous si un autre modèle de conception, comme la délégation ou d'une catégorie, ne rentrent plus facilement dans la lumière de la langue que vous utilisez.
Mais revenons aux délégués d'application. La grande différence entre UIApplicationDelegate et NSApplicationDelegate est en ce qu'ils sont. NSApplicationDelegate est un protocole informel, Ce qui signifie que c'est simplement une catégorie sur NSObject. Ci-dessous, vous pouvez voir ce NSApplicationDelegate ressemble dans Leopard. J'ai pris des commentaires et des macros pré-compilateur et reformaté pour le rendre plus facile à lire. Vous pouvez trouver l'original dans:
Cela peut sembler un peu étrange. Pourquoi devrions-nous déclarer une catégorie sur NSObject pour les méthodes de délégué? En fonction de vos antécédents linguistiques, vous pourriez vous demander pourquoi ce n'est pas un protocole ou d'interface. La réponse est simple, vraiment. En Objective-C antérieure à 2.0, les protocoles (parfois dénommé "protocole officiel") ne permet pas des méthodes facultatives. Si vous conformer à un protocole, vous avez eu à mettre en œuvre toutes les méthodes de ce protocole. Cela n'aurait pas fonctionné très bien, les ingénieurs d'Apple et de NeXT ne voulait pas forcer les programmeurs à répondre à toutes les méthodes concevables tout délégué application serait jamais besoin de leurs propres délégués. Plutôt, ils ont voulu laisser les programmeurs en œuvre que les méthodes qu'ils avaient besoin de déléguer. En le déclarant comme une catégorie et créer ce que nous appelons un «protocole informel", le compilateur et le programmateur nous dit quelles sont les méthodes par ce délégué peut répondre, mais aucune obligation n'est imposée au programmeur d'implémenter une méthode particulière. Il est parfaitement valide (stupide) d'un délégué à répondre à aucune des méthodes de délégué.
Dans l'approche de cacao aux délégués, la méthode mutateur pour un délégué ressemble généralement à ceci:
En d'autres termes, une instance de n'importe quelle classe peut être définie comme le délégué. Si ce délégué met en œuvre une méthode déléguée particulier, cette méthode sera appelée au moment approprié. Si ce n'est pas l'appliquer, NSApplication va simplement sauter l'appel et continuer l'exécution du programme. C'est une approche très laissez-faire qui met beaucoup de confiance dans le programmateur. C'est cacao en un mot, vraiment. Objective-C ne donne pas les mécanismes de programmeur de complètement verrouiller d'autres programmeurs la manière, disons, Java, C + + et C # ne. Il n'y a pas des classes finales, et les choses en déclarant @ private est vraiment plus d'une suggestion. La nature de la langue conduit à une approche différente de beaucoup de choses. Il peut sembler étrange - même mal - si vous venez d'une des nombreuses langues qui tirent leur modèle objet de l'extrême-Simula moins confiance, mais lui donner le temps. Correctement utilisé, il est très élégant.
D'un autre côté. UIApplicationDelegate, délégué application de l'iPhone, n'est pas implémentée en utilisant une catégorie, il est mis en œuvre en utilisant un protocole formel. Depuis l'iPhone a été développé après l'Objective-C 2.0 a été publié, Apple avait la possibilité d'utiliser des méthodes formelles dans les protocoles facultatifs, ainsi en Cocoa Touch plupart (je pense que tous) les délégués sont définies comme des protocoles formels. C'est ce que le délégué application ressemble à Cocoa Touch. Encore une fois, j'ai reformaté et supprimé des commentaires à faire lire plus facile dans ce contexte:
C'est vraiment pas si différent. Bien sûr, les méthodes délégué ne sont pas exactement les mêmes en raison de la nature différente des dispositifs pour lesquels le cacao et le Cocoa Touch ont été conçus, mais ce protocole dit essentiellement la même que notre protocole antérieur informelle dit: que tout objet peut être un délégué, et depuis il déclare toutes les méthodes que @ option, le délégué a seulement besoin de mettre en œuvre ces méthodes, il se soucie. La méthode mutateur pour un délégué de Cocoa Touch ressemble à celle de cacao, mais avec deux différences. Tout d'abord, UIApplication utilise les propriétés d'Objective-C 2.0 's et synthétise les mutator plutôt que de déclarer un mutator manuellement. Deuxièmement, et plus important, mais il accepte toujours id (ce qui signifie tout autre objet), il demande que l'objet étant désigné comme le délégué conformes au protocole UIApplicationDelegate:
Ceci étant Objective-C, vous pouvez assigner n'importe quelle réalité l'objet à la déléguée, même celui qui ne se conforment pas au protocole, mais si la classe de l'objet assigné ne fait pas explicitement conforme à UIApplicationDelegate, vous obtiendrez un avertissement à la compilation . Heureusement, tous les modèles d'application pour iPhone vous donne votre délégué application, et la classe le délégué fourni est conforme déjà à cette propriété, de sorte que vous rarement besoin de faire cette étape pour le délégué d'application, mais quand il vient aux délégués d'innombrables autres Cocoa Touch , vous devrez explicitement conformes votre classe au protocole de délégué.
Que cacao passeront à l'utilisation des protocoles officiels sont, dès maintenant, une question sans réponse. Jusqu'ici, je n'ai vu aucune indication d'Apple ce changement. Comme de Leopard, chaque délégué, je peux penser à est implémenté comme une catégorie sur NSObject, mais je ne dispose pas de plus information sur ce qui se passe dans l'intérieur de la boucle que la plupart d'entre vous font et ne savent pas si elles ont des plans pour changer cette situation. Ils pourraient. Ils ne pourraient pas.
Ce que je sais est que pas tout le monde convient que la nouvelle façon de faire des délégués est le meilleur. J'ai parlé à un certain nombre de vieux temps de cacao / Mac programmeurs qui considèrent la nouvelle approche que moins élégant et le voir comme un changement inutile. Je n'ai pas vraiment avoir beaucoup d'avis, pour être honnête. En pratique, il n'ya pas beaucoup de différence dans la façon dont nous utilisons les délégués des deux approches. Autre que pour se conformer à l'une de nos classes de protocole, à peu près tout fonctionne de la même.
La nouvelle approche est un compromis. Il ajoute quelques vérifications compilateur temps qui ne sont pas disponibles avec les protocoles informels, mais elle a aussi des conséquences imprévues. Par exemple, lorsque vous avez sous-classes de classes avec les délégués, vous pouvez avoir des situations où un délégué doit se conformer à un protocole pour un objet pour lequel ce n'est pas le délégué. Vous pouvez voir un exemple de cela dans Début de développement iPhone au chapitre 16. À la page 467, nous nous conformons aux CameraViewController UINavigationControllerDelegate, même si nous ne sommes pas un délégué d'un UINavigationController. Pourquoi? Parce UIImagePickerController est une sous-classe de UINavigationController. Parce que ces deux classes ont délégués et de leurs délégués nécessitent des protocoles différents. En conséquence, le compilateur nous force à se conformer aux deux protocoles. C'est un inconvénient plutôt mineur - il faut taper un nom de classe unique - mais cela semble se frotter certains développeurs Cocoa qui j'ai parlé comme étant très «anti-Cacao-like» et inélégant.
Voyons finir avec un dernier importante d'informations sur les délégués qui s'applique à la fois de cacao et Cocoa Touch: en règle générale, les objets ne pas envoyer une message à retenir, leur délégué. Il ya quelques exceptions à cela, mais à moins d'une classe est spécifiquement documentées comme conservant son délégué, supposer qu'ils n'en ont pas. Si votre délégué sera désallouée avant la classe, il est un délégué pour, vous devez vous assurer de mettre en déléguer la classe »à zéro avant votre classe est libérée pour éviter les problèmes.
La plus évidente de ces différences est que le concept de classes de contrôleur générique de vue est «cuit dans" à Cocoa Touch, mais ont été ajoutés au cacao, après qu'il a été autour depuis des années. Mais c'est un sujet pour un blog affichage distinct. Aujourd'hui, je veux parler de l'autre, la différence un peu plus subtile, qui est que le Touch Cacao et mettre en œuvre les délégués de manières complètement différentes. Regardons les objets déléguer plus couramment utilisées: les délégués d'application. Les deux cadres d'application des délégués-UIApplicationDelegate et NSApplicationDelegate-servir le même but, mais sont mises en oeuvre différemment.
Delegation n'est pas unique à l'Objective-C. C'est un modèle reconnu qui est utilisé dans de nombreuses langues, mais avec parcimonie dans la plupart des. En raison de l'Objective-C dynamique, la nature faiblement typé, la pomme et des ingénieurs de NeXT a réalisé très tôt que la délégation a souvent été un meilleur choix que l'héritage, ce qui explique pourquoi la hiérarchie de classes pour le cacao et Cocoa Touch est généralement plus plat que les hiérarchies de l'orienté objet cadres d'application intégré dans d'autres langues. Si vous venez à Objective-C récemment d'un autre langage OO, chaque fois que votre premier réflexe est de sous-classe, prendre du recul et demandez-vous si un autre modèle de conception, comme la délégation ou d'une catégorie, ne rentrent plus facilement dans la lumière de la langue que vous utilisez.
Mais revenons aux délégués d'application. La grande différence entre UIApplicationDelegate et NSApplicationDelegate est en ce qu'ils sont. NSApplicationDelegate est un protocole informel, Ce qui signifie que c'est simplement une catégorie sur NSObject. Ci-dessous, vous pouvez voir ce NSApplicationDelegate ressemble dans Leopard. J'ai pris des commentaires et des macros pré-compilateur et reformaté pour le rendre plus facile à lire. Vous pouvez trouver l'original dans
@interface NSObject(NSApplicationDelegate)
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames;
- (BOOL)application:(NSApplication *)sender openTempFile:(NSString *)filename;
- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender;
- (BOOL)application:(id)sender openFileWithoutUI:(NSString *)filename;
- (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename;
- (NSApplicationPrintReply)application:(NSApplication *)application
printFiles:(NSArray *)fileNames
withSettings:(NSDictionary *)printSettings
showPrintPanels:(BOOL)showPrintPanels;
- (void)application:(NSApplication *)sender printFiles:(NSArray *)filenames;
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag;
- (NSMenu *)applicationDockMenu:(NSApplication *)sender;
- (NSError *)application:(NSApplication *)application willPresentError:(NSError *)error;
@endCela peut sembler un peu étrange. Pourquoi devrions-nous déclarer une catégorie sur NSObject pour les méthodes de délégué? En fonction de vos antécédents linguistiques, vous pourriez vous demander pourquoi ce n'est pas un protocole ou d'interface. La réponse est simple, vraiment. En Objective-C antérieure à 2.0, les protocoles (parfois dénommé "protocole officiel") ne permet pas des méthodes facultatives. Si vous conformer à un protocole, vous avez eu à mettre en œuvre toutes les méthodes de ce protocole. Cela n'aurait pas fonctionné très bien, les ingénieurs d'Apple et de NeXT ne voulait pas forcer les programmeurs à répondre à toutes les méthodes concevables tout délégué application serait jamais besoin de leurs propres délégués. Plutôt, ils ont voulu laisser les programmeurs en œuvre que les méthodes qu'ils avaient besoin de déléguer. En le déclarant comme une catégorie et créer ce que nous appelons un «protocole informel", le compilateur et le programmateur nous dit quelles sont les méthodes par ce délégué peut répondre, mais aucune obligation n'est imposée au programmeur d'implémenter une méthode particulière. Il est parfaitement valide (stupide) d'un délégué à répondre à aucune des méthodes de délégué.
Dans l'approche de cacao aux délégués, la méthode mutateur pour un délégué ressemble généralement à ceci:
- (void)setDelegate:(id)anObject;En d'autres termes, une instance de n'importe quelle classe peut être définie comme le délégué. Si ce délégué met en œuvre une méthode déléguée particulier, cette méthode sera appelée au moment approprié. Si ce n'est pas l'appliquer, NSApplication va simplement sauter l'appel et continuer l'exécution du programme. C'est une approche très laissez-faire qui met beaucoup de confiance dans le programmateur. C'est cacao en un mot, vraiment. Objective-C ne donne pas les mécanismes de programmeur de complètement verrouiller d'autres programmeurs la manière, disons, Java, C + + et C # ne. Il n'y a pas des classes finales, et les choses en déclarant @ private est vraiment plus d'une suggestion. La nature de la langue conduit à une approche différente de beaucoup de choses. Il peut sembler étrange - même mal - si vous venez d'une des nombreuses langues qui tirent leur modèle objet de l'extrême-Simula moins confiance, mais lui donner le temps. Correctement utilisé, il est très élégant.
D'un autre côté. UIApplicationDelegate, délégué application de l'iPhone, n'est pas implémentée en utilisant une catégorie, il est mis en œuvre en utilisant un protocole formel. Depuis l'iPhone a été développé après l'Objective-C 2.0 a été publié, Apple avait la possibilité d'utiliser des méthodes formelles dans les protocoles facultatifs, ainsi en Cocoa Touch plupart (je pense que tous) les délégués sont définies comme des protocoles formels. C'est ce que le délégué application ressemble à Cocoa Touch. Encore une fois, j'ai reformaté et supprimé des commentaires à faire lire plus facile dans ce contexte:
@protocol UIApplicationDelegate<NSObject>
@optional
- (void)applicationDidFinishLaunching:(UIApplication *)application;
- (void)applicationDidBecomeActive:(UIApplication *)application;
- (void)applicationWillResignActive:(UIApplication *)application;
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;
- (void)applicationWillTerminate:(UIApplication *)application;
- (void)applicationSignificantTimeChange:(UIApplication *)application;
- (void)application:(UIApplication *)application
willChangeStatusBarOrientation:(UIInterfaceOrientation)newStatusBarOrientation
duration:(NSTimeInterval)duration;
- (void)application:(UIApplication *)application
didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation;
- (void)application:(UIApplication *)application
willChangeStatusBarFrame:(CGRect)newStatusBarFrame;
- (void)application:(UIApplication *)application
didChangeStatusBarFrame:(CGRect)oldStatusBarFrame;
@end
C'est vraiment pas si différent. Bien sûr, les méthodes délégué ne sont pas exactement les mêmes en raison de la nature différente des dispositifs pour lesquels le cacao et le Cocoa Touch ont été conçus, mais ce protocole dit essentiellement la même que notre protocole antérieur informelle dit: que tout objet peut être un délégué, et depuis il déclare toutes les méthodes que @ option, le délégué a seulement besoin de mettre en œuvre ces méthodes, il se soucie. La méthode mutateur pour un délégué de Cocoa Touch ressemble à celle de cacao, mais avec deux différences. Tout d'abord, UIApplication utilise les propriétés d'Objective-C 2.0 's et synthétise les mutator plutôt que de déclarer un mutator manuellement. Deuxièmement, et plus important, mais il accepte toujours id (ce qui signifie tout autre objet), il demande que l'objet étant désigné comme le délégué conformes au protocole UIApplicationDelegate:
@property(nonatomic,assign) id<UIApplicationDelegate> delegate;Ceci étant Objective-C, vous pouvez assigner n'importe quelle réalité l'objet à la déléguée, même celui qui ne se conforment pas au protocole, mais si la classe de l'objet assigné ne fait pas explicitement conforme à UIApplicationDelegate, vous obtiendrez un avertissement à la compilation . Heureusement, tous les modèles d'application pour iPhone vous donne votre délégué application, et la classe le délégué fourni est conforme déjà à cette propriété, de sorte que vous rarement besoin de faire cette étape pour le délégué d'application, mais quand il vient aux délégués d'innombrables autres Cocoa Touch , vous devrez explicitement conformes votre classe au protocole de délégué.
Que cacao passeront à l'utilisation des protocoles officiels sont, dès maintenant, une question sans réponse. Jusqu'ici, je n'ai vu aucune indication d'Apple ce changement. Comme de Leopard, chaque délégué, je peux penser à est implémenté comme une catégorie sur NSObject, mais je ne dispose pas de plus information sur ce qui se passe dans l'intérieur de la boucle que la plupart d'entre vous font et ne savent pas si elles ont des plans pour changer cette situation. Ils pourraient. Ils ne pourraient pas.
Ce que je sais est que pas tout le monde convient que la nouvelle façon de faire des délégués est le meilleur. J'ai parlé à un certain nombre de vieux temps de cacao / Mac programmeurs qui considèrent la nouvelle approche que moins élégant et le voir comme un changement inutile. Je n'ai pas vraiment avoir beaucoup d'avis, pour être honnête. En pratique, il n'ya pas beaucoup de différence dans la façon dont nous utilisons les délégués des deux approches. Autre que pour se conformer à l'une de nos classes de protocole, à peu près tout fonctionne de la même.
La nouvelle approche est un compromis. Il ajoute quelques vérifications compilateur temps qui ne sont pas disponibles avec les protocoles informels, mais elle a aussi des conséquences imprévues. Par exemple, lorsque vous avez sous-classes de classes avec les délégués, vous pouvez avoir des situations où un délégué doit se conformer à un protocole pour un objet pour lequel ce n'est pas le délégué. Vous pouvez voir un exemple de cela dans Début de développement iPhone au chapitre 16. À la page 467, nous nous conformons aux CameraViewController UINavigationControllerDelegate, même si nous ne sommes pas un délégué d'un UINavigationController. Pourquoi? Parce UIImagePickerController est une sous-classe de UINavigationController. Parce que ces deux classes ont délégués et de leurs délégués nécessitent des protocoles différents. En conséquence, le compilateur nous force à se conformer aux deux protocoles. C'est un inconvénient plutôt mineur - il faut taper un nom de classe unique - mais cela semble se frotter certains développeurs Cocoa qui j'ai parlé comme étant très «anti-Cacao-like» et inélégant.
Voyons finir avec un dernier importante d'informations sur les délégués qui s'applique à la fois de cacao et Cocoa Touch: en règle générale, les objets ne pas envoyer une message à retenir, leur délégué. Il ya quelques exceptions à cela, mais à moins d'une classe est spécifiquement documentées comme conservant son délégué, supposer qu'ils n'en ont pas. Si votre délégué sera désallouée avant la classe, il est un délégué pour, vous devez vous assurer de mettre en déléguer la classe »à zéro avant votre classe est libérée pour éviter les problèmes.
Aucun commentaire:
Enregistrer un commentaire