<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>netinfluence&#039;s blog &#187; best practices</title>
	<atom:link href="http://blog.netinfluence.com/tag/best-practices/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.netinfluence.com</link>
	<description>le blog de l&#039;agence netinfluence</description>
	<lastBuildDate>Fri, 13 Jan 2012 10:39:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Comment faire grandir son business sur Facebook: le cas de Dein Deal</title>
		<link>http://blog.netinfluence.com/2011/03/25/comment-faire-grandir-son-business-sur-facebook-le-cas-de-dein-deal/</link>
		<comments>http://blog.netinfluence.com/2011/03/25/comment-faire-grandir-son-business-sur-facebook-le-cas-de-dein-deal/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 09:37:13 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[reach]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[Branding & Social Media]]></category>
		<category><![CDATA[dein deal]]></category>
		<category><![CDATA[facebook ads]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.com/?p=4206</guid>
		<description><![CDATA[Le dernier intervenant de la conférence Branding &#038; Social Media, Flavio Rump, est co-fondateur de deindeal.ch. Il nous a parlé du meilleur moyen pour faire grandir son business sur Facebook. Dein Deal est passé de 5 à 50 employés en 5 ans et est présent dans de nombreuses régions suisses. Business à la Groupon, Dein Deal propose une affaire par jour avec un rabais allant de 50 à 70%. 100&#8217;000 coupons ont déjà été vendus! Dein Deal de part sa présence sur internet, se doit d’avoir une stratégie social média. A chaque offre, un poste de l&#8217;offre est laissé sur leurs pages Facebook réparties par zones géographiques. S’en viennent automatiquement des commentaires laissés par les clients. Ceci permet à Dein [...]]]></description>
			<content:encoded><![CDATA[<p>Le dernier intervenant de la conférence Branding &#038; Social Media, Flavio Rump, est co-fondateur de <a href="http://www.deindeal.ch">deindeal.ch</a>. Il nous a parlé du meilleur moyen pour faire grandir son business sur Facebook.</p>
<p>Dein Deal est passé de 5 à 50 employés en 5 ans et est présent dans de nombreuses régions suisses. Business à la <a href="http://www.groupon.ch/">Groupon</a>, Dein Deal propose une affaire par jour avec un rabais allant de 50 à 70%. 100&#8217;000 coupons ont déjà été vendus!</p>
<p><a href="http://www.deindeal.ch/">Dein Deal</a> de part sa présence sur internet, se doit d’avoir une stratégie social média.</p>
<p>A chaque offre, un poste de l&#8217;offre est laissé sur leurs <a href="http://www.facebook.com/DeinDeal.Zurich?ref=ts">pages Facebook</a> réparties par zones géographiques. S’en viennent automatiquement des commentaires laissés par les clients. Ceci permet à Dein Deal d’avoir tous types de feed-back et de mieux comprendre ce que désirent leurs clients. Par exemple, si un nombre important de personnes réclament un certain type de Deal, il sera fait selon les possibilités pour leur en proposer un. Dans un second temps, ceci permet de fidéliser une clientèle satisfaite qui sera enclin à partager des offres avec leurs amis.</p>
<p>Afin de mettre au courant des personnes n’ayant pas encore entendu parler de Dein Deal, de la publicité est faite sur Facebook. Cette publicité permet,grâce aux différents critères que propose Facebook, de cibler très précisément les personnes suséptibles d’être intéréssées par une offre.</p>
<p>Pour optimiser ces publicités: 30 différentes seront mises en ligne et leurs performances mesurées et suivient. Celle dont le taux de clic et de conversion marche le mieux sera gardée. Les autres publicités sont supprimées et leur budget reversé dans celui de la publicité qu&#8217;on aura décidé de garder.</p>
<p>Pour en savoir plus, voici ses slides.</p>
<div id="__ss_7273164" style="width: 425px;"><strong><a title="Comment faire grandir son business sur Facebook?" href="http://www.slideshare.net/olivier.enigma/comment-faire-grandir-son-business-sur-facebook">Comment faire grandir son business sur Facebook?</a></strong> <object id="__sse7273164" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=presflaviorump-110315122348-phpapp01&amp;stripped_title=comment-faire-grandir-son-business-sur-facebook&amp;userName=olivier.enigma" /><param name="name" value="__sse7273164" /><param name="allowfullscreen" value="true" /><embed id="__sse7273164" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=presflaviorump-110315122348-phpapp01&amp;stripped_title=comment-faire-grandir-son-business-sur-facebook&amp;userName=olivier.enigma" name="__sse7273164" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="padding: 5px 0 12px;">View more presentations from <a href="http://www.slideshare.net/olivier.enigma">Olivier Perez Kennedy</a></div>
</div>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2011/03/25/comment-faire-grandir-son-business-sur-facebook-le-cas-de-dein-deal/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>XCode: librairies statiques et catégories</title>
		<link>http://blog.netinfluence.com/2010/06/23/xcode-librairies-statiques-et-categories/</link>
		<comments>http://blog.netinfluence.com/2010/06/23/xcode-librairies-statiques-et-categories/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 14:56:36 +0000</pubDate>
		<dc:creator>macmade</dc:creator>
				<category><![CDATA[create]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[conseils]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[XCode]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=1926</guid>
		<description><![CDATA[Il est souvent pratique de scinder un projet XCode en plusieurs parties distinctes: le code permettant de contrôler les différents éléments de l'interface, et le code indépendant de l'interface (outils, librairies, etc).
Une telle découpe présente de nombreux avantage, notamment un meilleur contrôle des options de compilation pour chaque partie ainsi q'un temps de compilation réduit, puisque chaque partie est compilée séparément, et uniquement en cas de besoin.
Cet article explique comment paramétrer un projet XCode pour une telle utilisation.]]></description>
			<content:encoded><![CDATA[<div class="macmade-grey">
<div class="macmade-small"> Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be found at: <a href="http://www.gnu.org/copyleft/fdl.html" title="Free Documentation License">http://www.gnu.org/copyleft/fdl.html</a></div>
</div>
<div>
Il est souvent pratique de scinder un projet XCode en plusieurs parties distinctes: le code permettant de contrôler les différents éléments de l&#8217;interface, et le code indépendant de l&#8217;interface (outils, librairies, etc).<br />
Une telle découpe présente de nombreux avantage, notamment un meilleur contrôle des options de compilation pour chaque partie ainsi q&#8217;un temps de compilation réduit, puisque chaque partie est compilée séparément, et uniquement en cas de besoin.<br />
Cet article explique comment paramétrer un projet XCode pour une telle utilisation.
</div>
<h2>Création d&#8217;un projet</h2>
<div>
Nous allons tout d&#8217;abord créer un nouveau projet XCode pour iPhone (la procédure est exactement similaire dans le cas d&#8217;une application Mac OS X).
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-1.png" />
</div>
<div>
XCode crée par défaut les fichiers nécessaires au fonctionnement d&#8217;une application basique.
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-2.png" />
</div>
<div>
La section «Targets» comprend les différents éléments pouvant être produits par notre projet XCode.
</div>
<div>
Dans ce cas là, il s&#8217;agit d&#8217;une application. Ce type de cible est composée de la copie des resources (les fichiers XIB &#8211; interface utilisateur), de la compilation du code source de l&#8217;application, et finalement de la liaison (lainage) du code objet généré avec les librairies et frameworks utilisés par l&#8217;application.
</div>
<div>
Il est possible de définir pour une cible des paramètres de compilation spécifiques, via le menu contextuel,
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-3.png" />
</div>
<h2>Cibles</h2>
<div>
Un projet XCode peut être composé de plusieurs cibles. Cela est nécessaire si l&#8217;on intègre des librairies externes, mais cela peut également être pratique pour séparer un projet et ainsi optimiser la compilation de l&#8217;application finale.
</div>
<div>
Nous allons commencer par créer une nouvelle classe, que nous allons nommer «MethodProvider», dont le but est, comme son nom l&#8217;indique, de mettre à disposition des méthode génériques pour notre application.
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-4.png" />
</div>
<div>
Nous allons y intégrer une méthode statique nommée doSomething.
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-comment">/* MethodProvider.h */</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">#import</span> <span class="macmade-code-string">&lt;UIKit/UIKit.h&gt;</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@interface</span> MethodProvider: NSObject</code><br />
<code class="macmade-source">{}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">+ ( <span class="macmade-code-keyword">void</span> )doSomething;</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code>
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-comment">/* MethodProvider.m */</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">#import</span> <span class="macmade-code-string">"MethodProvider.h"</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> MethodProvider</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">+ ( <span class="macmade-code-keyword">void</span> )doSomething</code><br />
<code class="macmade-source">{</code><br />
<code class="macmade-source">    <span class="macmade-code-predefined">NSLog</span>( <span class="macmade-code-string">@"Method 'doSomething' called..."</span> );</code><br />
<code class="macmade-source">}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code>
</div>
<div>
Nous allons également appeler cette méthode depuis notre application, lorsque celle-ci aura terminé son chargement. Cela se passe dans la méthode «application:didFinishLaunchingWithOptions:»  de la classe «MyAppAppDelegate»:
</div>
<div class="macmade-code">
<code class="macmade-source">- ( <span class="macmade-code-keyword">BOOL</span> )application: ( <span class="macmade-code-predefined">UIApplication</span> * )application didFinishLaunchingWithOptions: ( <span class="macmade-code-predefined">NSDictionary</span> * )launchOptions</code><br />
<code class="macmade-source">{</code><br />
<code class="macmade-source">    [ <span class="macmade-code-ctag">window</span> <span class="macmade-code-predefined">addSubview</span>: <span class="macmade-code-ctag">viewController</span>.<span class="macmade-code-predefined">view</span> ];</code><br />
<code class="macmade-source">    [ <span class="macmade-code-ctag">window</span> makeKeyAndVisible ];</code><br />
<code class="macmade-source">    </code><br />
<code class="macmade-source">    [ <span class="macmade-code-ctag">MethodProvider</span> doSomething ];</code><br />
<code class="macmade-source">    </code><br />
<code class="macmade-source">    <span class="macmade-code-keyword">return YES</span>;</code><br />
<code class="macmade-source">}</code>
</div>
<div>
Ne pas oublier d&#8217;include le fichier .h de la classe «MethodProvider» dans le fichier «MyAppAppController.m»:
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-keyword">#import</span> <span class="macmade-code-string">"MyAppAppDelegate.h"</span></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">#import</span> <span class="macmade-code-string">"MyAppViewController.h"</span></code><br />
<code class="macmade-source"><strong><span class="macmade-code-keyword">#import</span> <span class="macmade-code-string">"MethodProvider.h"</span></strong></code>
</div>
<div>
Dans ce cas là, la classe «MethodProvider» est compilée avec les autres fichiers sources de notre application. Nous allons maintenant faire en sorte qu&#8217;elle le soit séparément.
</div>
<div>
En premier lieu, nous allons ôter cette classe de la cible de notre application. Cela peut être effectué en décochant la case à côté du fichier source.
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-5.png" />
</div>
<div>
A partir de ce moment là, la classe ne sera plus compilée en même temps que l&#8217;application. La compilation de l&#8217;application va donc échouer avec le message suivant:
</div>
<div>
<pre>
_OBJC_CLASS_$_MethodProvider", referenced from:
objc-class-ref-to-MethodProvider in MyAppAppDelegate.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
</pre>
</div>
<div>
Ce message veut tout simplement dire que le linker n&#8217;a pas réussi à trouver le symbole correspondant à notre classe, alors qu&#8217;il est utilisé depuis la classe MyAppAppDelegate.
</div>
<div>
Nous allons donc créer une nouvelle cible, qui aura pour but de compiler la classe «MethodProvider».
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-6.png" />
</div>
<h2>Librairie statique</h2>
<div>
Cette cible sera de type «static library»:
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-7.png" />
</div>
<div>
Une librairie est un format spécifique de code object (compilé), dont le but est de fournir des fonctions aux applications désirant les utiliser. Une librairie peut être de deux types: statique ou dynamique.
</div>
<div>
Dans le cas d&#8217;une librairie statique, le code objet de la librairie est intégré au binaire de l&#8217;application lors de la compilation.<br />
Il en résulte un seul fichier binaire, contenant à la fois le code de l&#8217;application et le code de la librairie. Le binaire est donc plus lourd, mais la libraire n&#8217;a pas besoin d&#8217;être présente sur la machine hôte.
</div>
<div>
Dans le cas d&#8217;une librairie dynamique, seul son adresse est inclue dans le code de l&#8217;application, et c&#8217;est le kernel (via un linker) qui chargera le code de la libraire en mémoire à chaque fois que l&#8217;application est lancée. Le binaire est dans ce cas plus léger, mais la librairie doit impérativement être présente sur la machine hôte. Le temps de lancement de l&#8217;application peut en outre être un peu plus long. Le principal avantage d&#8217;une librairie dynamique est que plusieurs applications peuvent reposer sur la même librairie.
</div>
<div>
Dans notre cas, c&#8217;est donc bien sûr une libraire statique qu&#8217;il nous faut. Qui plus est, sur iOS, il est actuellement impossible de générer une libraire dynamique.
</div>
<div>
Lorsque plusieurs cibles sont disponibles, XCode permet de passer de l&#8217;une à l&#8217;autre via un menu déroulant, se trouvant dans la barre d&#8217;outils:
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-8.png" />
</div>
<div>
Nous pouvons donc passer sur notre cible «Methods», et y ajouter le(s) fichiers devant être compilés:
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-9.png" />
</div>
<div>
Nous pouvons également voir, au passage, notre librairie dans la section «Products»:
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-10.png" />
</div>
<div>
Il nous reste à lier notre application principale avec cette librairie. Cela est effectué depuis la phase «Link Binary With Libraries» de la cible de l&#8217;application.
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-11.png" />
</div>
<div>
Nous pouvons maintenant y ajouter notre librairie.
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-12.png" />
</div>
<div>
La dernière étape consiste à indiquer à XCode que notre application dépend de la librairie, pour que cette dernière soit compilée avant l&#8217;application, en cas de besoin. Cette opération est effectuée en ajoutant une dépendance, dans la section «General», dans les informations de la cible de l&#8217;application:
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-13.png" />
</div>
<div>
Nous pouvons maintenant compiler notre application sans problème.
</div>
<div>
Cette procédure peut être utilisée, comme dans cet exemple, pour séparer différentes parties de notre code.<br />
C&#8217;est également la procédure à utiliser lors de l&#8217;utilisation de sources et librairies externes, comme par exemple OpenCV (C++), JSON-Framework (Obj-C), etc.<br />
Il est bien sûr possible d&#8217;inclure les fichiers sources dans la même cible que l&#8217;application, mais un tel scénario nous prive de la possibilité de spécifier des paramètres de compilation spécifiques et risque de rallonger inutilement le temps de compilation de la cible principale.
</div>
<h2>Catégories</h2>
<div>
Il faut encore noter que, dans le cas de l&#8217;utilisation de catégories, l&#8217;utilisation d&#8217;une librairie statique peut se révéler problématique.<br />
Pour rappel, en Objective-C, une catégorie permet d&#8217;ajouter des méthodes dans une classe existante.
</div>
<div>
Ajoutons donc une catégorie sur UIApplication, dans la cible de notre librairie:
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-comment">/* MyUIApp.h */</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">#import</span> <span class="macmade-code-string">&lt;UIKit/UIKit.h&gt;</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@interface</span> UIApplication( MyUIApp )</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )sayHello;</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code>
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-comment">/* MyUIApp.m */</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">#import</span> <span class="macmade-code-string">"MyUIApp.h"</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> UIApplication( MyUIApp )</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )sayHello</code><br />
<code class="macmade-source">{</code><br />
<code class="macmade-source">    <span class="macmade-code-predefined">NSLog</span>( <span class="macmade-code-string">@"Hello"</span> );</code><br />
<code class="macmade-source">}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code>
</div>
<div>
Et utilisons cette méthode dans notre application:
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-comment">/* MyAppAppDelegate.m */</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">BOOL</span> )application: ( <span class="macmade-code-predefined">UIApplication</span> * )application didFinishLaunchingWithOptions: ( <span class="macmade-code-predefined">NSDictionary</span> * )launchOptions</code><br />
<code class="macmade-source">{</code><br />
<code class="macmade-source">    [ <span class="macmade-code-ctag">window</span> <span class="macmade-code-predefined">addSubview</span>: <span class="macmade-code-ctag">viewController</span>.<span class="macmade-code-predefined">view</span> ];</code><br />
<code class="macmade-source">    [ <span class="macmade-code-ctag">window</span> makeKeyAndVisible ];</code><br />
<code class="macmade-source">    </code><br />
<code class="macmade-source">    [ <span class="macmade-code-ctag">MethodProvider</span> doSomething ];</code><br />
<code class="macmade-source">    [ application sayHello ];</code><br />
<code class="macmade-source">    </code><br />
<code class="macmade-source">    <span class="macmade-code-keyword">return YES</span>;</code><br />
<code class="macmade-source">}</code>
</div>
<div>
Sans oublier d&#8217;inclure le fichier header:
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-keyword">#import</span> <span class="macmade-code-string">"MyUIApp.h"</span></code>
</div>
<div>
La compilation se déroulera sans aucun problème, mais l&#8217;application plantera, avec le message suivant (affiché dans la console):
</div>
<div>
<pre>
- [ UIApplication sayHello ]: unrecognized selector sent to instance 0x5911700
</pre>
</div>
<div>
Ce cas particulier est dû au côté dynamique d&#8217;Objective-C (la résolution des méthodes est faite par la couche run-time), est au spécificités du linker, qui ne génère par défaut pas de symboles pour les catégories.
</div>
<div>
Pour régler ce problème, il suffit de modifier les paramètres du linker, dans les informations de la cible de l&#8217;application, et y ajouter, dans la section «Other Linker Flags»:
</div>
<div>
<pre>
-ObjC -all_load
</pre>
</div>
<div>
<img src="/wp-content/uploads/macmade/objc-lib-14.png" />
</div>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2010/06/23/xcode-librairies-statiques-et-categories/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Second Day of Marketing 2 Conference</title>
		<link>http://blog.netinfluence.com/2010/03/26/second-day-of-marketing-2-conference/</link>
		<comments>http://blog.netinfluence.com/2010/03/26/second-day-of-marketing-2-conference/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 10:42:06 +0000</pubDate>
		<dc:creator>sandrine</dc:creator>
				<category><![CDATA[think]]></category>
		<category><![CDATA[BBC]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[brand institute]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[Electronic Arts]]></category>
		<category><![CDATA[Forbes]]></category>
		<category><![CDATA[humanizing]]></category>
		<category><![CDATA[IBM]]></category>
		<category><![CDATA[innocentive]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[Marketing2conference]]></category>
		<category><![CDATA[Matthias Lüfkens]]></category>
		<category><![CDATA[nils andres]]></category>
		<category><![CDATA[oke muller]]></category>
		<category><![CDATA[social media strategy]]></category>
		<category><![CDATA[TBWA]]></category>
		<category><![CDATA[vanksen]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=1602</guid>
		<description><![CDATA[The second day of the conference offered quite a few tracks on media and poor sales pitch of speaking sponsors.  To me, most of the presentations, unlike day1, were useless.  I however met up with some really interesting people, had a long talk about 2011 version of the event with Emmanuel Vivier (which was really interesting, looking forward) and discussed with Jean François Ruiz about his upcoming (and quite interesting) new product (much ado about social media profiling).  So my day, although poor in inspiration, was really rich networking wise! But, 1 presentation struck me and actually made my day.  Oke Müller, from TBWA did a superb and well handled keynote.  I filmed it and you must see the videos [...]]]></description>
			<content:encoded><![CDATA[<p>The second day of the conference offered quite a few tracks on media and poor sales pitch of speaking sponsors.  To me, most of the presentations, unlike day1, were useless.  I however met up with some really interesting people, had a long talk about 2011 version of the event with Emmanuel Vivier (which was really interesting, looking forward) and discussed with <a title="Jean francois ruiz" href="http://www.webdeux.info/author/jean-francois-ruiz" target="_blank">Jean François Ruiz</a> about his upcoming (and quite interesting) new product (much ado about social media profiling).  So my day, although poor in inspiration, was really rich networking wise!</p>
<p>But, 1 presentation struck me and actually made my day.  <a href="http://www.marketing2conference.com/2010/speaker_view.php?speaker_id=10" target="_blank">Oke Müller</a>, from TBWA did a superb and well handled keynote.  I filmed it and you must see the videos : <a title="Part 1" href="http://www.youtube.com/watch?v=Yg5F3ABldb4" target="_blank">Oke Muller part 1</a>- <a title="Part 2" href="http://www.youtube.com/watch?v=VdhbF4LZnoc&amp;feature=related" target="_blank">Oke Muller part 2</a> &#8211; <a title="Part 3" href="Marketing2Conference - Successful projects by TBWA - part3 " target="_blank">Oke Muller part 3</a>.</p>
<p>Also worth mentioning the <a title="EA presentation" href="http://www.youtube.com/watch?v=82dR0BjnDww" target="_blank">EA presentation</a>, <a title="Fererro" href="http://www.youtube.com/watch?v=-IW1pcMej8Y" target="_blank">Fererro</a>, <a title="innocentive" href="http://www.youtube.com/user/NetinfluenceChannel?feature=mhw5#p/u/8/7JPRpfkMmh4" target="_blank">innocentive</a> and of course our national <a title="Matthias luefkens" href="http://www.youtube.com/watch?v=bAwM1pIY_Ro" target="_blank">Matthias Luefkens</a>. I am just sad my battery went of due the (never ending) presentation of Marc Davis, so the last presentation were either shortened (that of matthias) or taken from my mac <img src='http://blog.netinfluence.com/wp-content/plugins/smilies-themer/Silk/emoticon_unhappy.png' alt=';-(' class='wp-smiley' /> </p>
<p>Next year I will not forget my charger&#8230;promise <img src='http://blog.netinfluence.com/wp-content/plugins/smilies-themer/Silk/emoticon_wink.png' alt=';-)' class='wp-smiley' /> </p>
<p>So, to wrap up with all this, yes this year edition, thanks to Nils, to Emmanuel and their teams was great. I will and you should come next year!</p>
<p>I hope that next year we get more of the Crispin and bogulsky or TBWA type of presentations and no more media boring stuff.  Maybe we too get the chance for prior the event animation (contest? agencies involved in the buzzing the conference, list of attendees and a feed of their tweets or blogs) and no more of the web 0 type of stuff like flyers distributed or crapy sponsor presentations.  Boy, this is not because you pay for the conference, you have to give boring sales pitch!  Maybe danone could create a product discovery and arrange a nice lounge area for people to experience a nice time during the breaks, so could Evian or Lego too.  Maybe the organizer should show the backchannel via <a title="visible tweets" href="http://visibletweets.com/#query=netinfluence&amp;animation=3" target="_blank">visibletweets</a> so that presenters get to be challenged and people in the room get to read what is said.<br />
Please, Nils, limit speakers to 10 minutes.  I did only take the last 10 minutes (to be allowed to download on youtube) of each presentations and believe me, the interesting bits fit in that, rest is boring!  Keep the schedule (you can&#8217;t be 2 hours late already at lunch time!)<br />
Food was nice, Wifi slow (but existing) and you did very well because, amonsgt the conference I attended, this one is one that brings me most value from a marketing standpoint.  So thank you and keep up the good (very good!) work.</p>
<p>You can access all the other video via our <a title="Youtube playlist of  netinfluence" href="http://www.youtube.com/user/NetinfluenceChannel#grid/user/A037B31972D8DA6B" target="_blank">netinfluenceChannel</a> on youtube.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2010/03/26/second-day-of-marketing-2-conference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Brand engagement via social networks – Business Cases from the M2C</title>
		<link>http://blog.netinfluence.com/2010/03/23/brand-engagement-via-social-networks-business-cases-from-the-m2c/</link>
		<comments>http://blog.netinfluence.com/2010/03/23/brand-engagement-via-social-networks-business-cases-from-the-m2c/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 06:00:34 +0000</pubDate>
		<dc:creator>sandrine</dc:creator>
				<category><![CDATA[grow]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[brand institute]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[Dell]]></category>
		<category><![CDATA[dunkin donuts]]></category>
		<category><![CDATA[evian]]></category>
		<category><![CDATA[general mills]]></category>
		<category><![CDATA[general motors]]></category>
		<category><![CDATA[humanizing]]></category>
		<category><![CDATA[IBM]]></category>
		<category><![CDATA[intel]]></category>
		<category><![CDATA[lego]]></category>
		<category><![CDATA[M2C]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[Marketing2conference]]></category>
		<category><![CDATA[nils andres]]></category>
		<category><![CDATA[P&G]]></category>
		<category><![CDATA[social media strategy]]></category>
		<category><![CDATA[vanksen]]></category>
		<category><![CDATA[wallmart]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=1565</guid>
		<description><![CDATA[Marketing2Conference, I attended last year for the first time, happened to be a great discovery.  Full of business cases and testimonial of humble brands explaining how they were trying their way out on social media, we were offered a very valuable content. What happens when you liked it one year, is that you expect the content to keep the good pace but often get disapointed. Definetly, the M2C conference is really an exception to this rule. The content this year is even more interesting.  Probably because a lot of brands did some trial and learnings over the past year, but most obviously because of the good combination of Nils Andres powerful network and of the vanksen team relentless efforts to [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-1567" href="http://blog.netinfluence.com/2010/03/23/brand-engagement-via-social-networks-business-cases-from-the-m2c/sany0085/"><img class="alignleft size-medium wp-image-1567" title="General Mills marketing manager @M2C" src="http://blog.netinfluence.ch/wp-content/uploads/2010/03/SANY0085-300x225.jpg" alt="" width="300" height="225" /></a>Marketing2Conference, I attended last year for the first time, happened to be a great discovery.  Full of business cases and testimonial of humble brands explaining how they were trying their way out on social media, we were offered a very valuable content.</p>
<p>What happens when you liked it one year, is that you expect the content to keep the good pace but often get disapointed. Definetly, the M2C conference is really an exception to this rule.</p>
<p>The content this year is even more interesting.  Probably because a lot of brands did some trial and learnings over the past year, but most obviously because of the good combination of Nils Andres powerful network and of the vanksen team relentless efforts to keep up with good buzz.</p>
<p>So, this year, to get prepared for the good, I came up with my brand new video to keep track of the best bits.</p>
<p>And what I did was quite special.  I decided to only film the last 10 minutes.  Most of the presenters only start to get in the really good stuff at the end.  And believe it or not, apart from one presentation (dunkin donut) I indeed captured the best extracts.</p>
<p>So here is my contribution to sharing the best of best of reknown brands best practices in terms of brand advocacy using web 2.0 strategies.</p>
<p>I really advise my favorites, namely dunkin donut for the clever online strategy, P&amp;G for the cognitive approach, Emmanuel Vivier for the &#8220;get real&#8221; message to customers, Evian for the master presentation of their latest incredible viral campaign and wallmart for their ability to catch the train &#8211; late &#8211; but successfully.</p>
<p>Hope you will like the videos.  And if you do, please leave me comments and ranks the videos accordingly so that I get a feedback of how you like them too <img src='http://blog.netinfluence.com/wp-content/plugins/smilies-themer/Silk/emoticon_wink.png' alt=';-)' class='wp-smiley' /> </p>
<p>Here is the evian video:</p>
<object type="application/x-shockwave-flash" style="width:425px; height:355px;" data="http://www.youtube.com/v/TY44Q84-Nto&amp;rel=1&amp;color1=0xd6d6d6&amp;color2=0xf0f0f0&amp;autoplay=1"><param name="movie" value="http://www.youtube.com/v/TY44Q84-Nto&amp;rel=1&amp;color1=0xd6d6d6&amp;color2=0xf0f0f0&amp;autoplay=1" /></object>
<p>You can access all the other video via our <a title="Youtube playlist of netinfluence" href="http://www.youtube.com/user/NetinfluenceChannel#grid/user/A037B31972D8DA6B" target="_blank">netinfluenceChannel</a> on youtube.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2010/03/23/brand-engagement-via-social-networks-business-cases-from-the-m2c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Méthodes privées en Objective-C</title>
		<link>http://blog.netinfluence.com/2010/03/04/methodes-privees-en-objective-c/</link>
		<comments>http://blog.netinfluence.com/2010/03/04/methodes-privees-en-objective-c/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 12:44:02 +0000</pubDate>
		<dc:creator>macmade</dc:creator>
				<category><![CDATA[create]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=1295</guid>
		<description><![CDATA[En Objective-C, contrairement à de nombreux autres langages orientés objet, le concept de méthode privée n'existe pas en tant que tel. Ce concept peut par contre être implémenté de plusieurs façons. Cet article présente 3 solutions possibles, avec leurs avantages et inconvénients.]]></description>
			<content:encoded><![CDATA[<div class="macmade-grey">
<div class="macmade-small"> Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be found at: <a href="http://www.gnu.org/copyleft/fdl.html" title="Free Documentation License">http://www.gnu.org/copyleft/fdl.html</a></div>
</div>
<h2>Introduction</h2>
<div>
En Objective-C, contrairement à de nombreux autres langages orientés objet, le concept de méthode privée n&#8217;existe pas en tant que tel.
</div>
<div>
Dans la déclaration de l&#8217;interface d&#8217;une classe, il est possible de définir une visibilité pour les variables d&#8217;instances.
</div>
<div>
Par exemple:
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-keyword">@interface</span> Foo: NSObject</code><br />
<code class="macmade-source">{</code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@public</span></code><br />
<code class="macmade-source">	</code><br />
<code class="macmade-source">	<span class="macmade-code-keyword">id</span> <span class="macmade-code-ctag">somePublicObject</span>;</code><br />
<code class="macmade-source">	</code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@protected</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">	<span class="macmade-code-keyword">id</span> <span class="macmade-code-ctag">someProtectedObject</span>;</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@private</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">	<span class="macmade-code-keyword">id</span> <span class="macmade-code-ctag">somePrivateObject</span>;</code><br />
<code class="macmade-source">}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">+ ( <span class="macmade-code-keyword">void</span> )someStaticMethod;</code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )someMemberMethod;</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code>
</div>
<div>
Les variables d&#8217;instances peuvent être regroupées en fonction de leur visibilité: publique (accessible depuis l&#8217;extérieur), protégée (accessible depuis la classe et les classes filles), et privée (accessible depuis la classe uniquement).
</div>
<div>
Il n&#8217;existe rien de tel pour les méthodes, au niveau de la déclaration de l&#8217;interface. Cependant, il est parfaitement possible d&#8217;implémenter le concept de méthodes privées, et ce de plusieurs façons.
</div>
<h2>Solution 1 &#8211; Implémentation</h2>
<div>
La première solution, et sans doute la plus évidente, consiste simplement à déclarer des méthodes dans l&#8217;implémentation.<br />
Dans un tel cas, ces méthodes ne seront pas visibles depuis l&#8217;extérieur, étant donné qu&#8217;elles ne sont pas présentes dans l&#8217;interface.
</div>
<div>
Par exemple:
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-keyword">@interface</span> Foo: NSObject</code><br />
<code class="macmade-source">{}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )somePublicMethod;</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> Foo</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )somePrivateMethod</code><br />
<code class="macmade-source">{}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )somePublicMethod</code><br />
<code class="macmade-source">{</code><br />
<code class="macmade-source">	[ <span class="macmade-code-keyword">self</span> <span class="macmade-code-ctag">somePrivateMethod</span> ];</code><br />
<code class="macmade-source">}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code>
</div>
<div>
Le principal problème avec cette approche est que les méthodes &#8220;privées&#8221; doivent impérativement être déclarées avant le code y faisant référence, sous peine d&#8217;une erreur lors de la compilation.<br />
Dans l&#8217;exemple précédent, nous n&#8217;aurions pas pu déclarer &#8220;somePublicMethod&#8221; avant &#8220;somePrivateMethod&#8221;.<br />
Dans certains cas, lors d&#8217;appels cycliques par exemple, il est tout simplement impossible d&#8217;utiliser cette solution.
</div>
<h2>Solution 2 &#8211; Fonctions statiques</h2>
<div>
Une deuxième solution consiste à l&#8217;utilisation de fonctions statiques.<br />
En langage C, une fonction statique n&#8217;est visible que pour les fonctions se trouvant dans le même fichier.<br />
Il est à noter que, bien que l&#8217;on utilise également dans ce cas le mot clé &#8216;static&#8217;, celui-ci à un tout autre sens que si on l&#8217;utilise pour une variable, à l&#8217;intérieur d&#8217;une fonction.
</div>
<div>
Autrement dit:
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> Foo</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">static void</span> somePrivateFunction( <span class="macmade-code-keyword">void</span> );</code><br />
<code class="macmade-source"><span class="macmade-code-keyword">static void</span> somePrivateFunction( <span class="macmade-code-keyword">void</span> )</code><br />
<code class="macmade-source">{}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )somePublicMethod</code><br />
<code class="macmade-source">{</code><br />
<code class="macmade-source">	<span class="macmade-code-ctag">somePrivateFunction</span>();</code><br />
<code class="macmade-source">}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code>
</div>
<div>
Il s&#8217;agit d&#8217;une fonction, et non d&#8217;une méthode. Il est par contre possible, depuis cette fonction, d&#8217;accéder aux autres méthodes, et même aux variables d&#8217;instances.<br />
Pour réaliser cela, il suffit de passer l&#8217;instance en paramètre de la fonction:
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> Foo</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">static void</span> somePrivateFunction( Foo * obj );</code><br />
<code class="macmade-source"><span class="macmade-code-keyword">static void</span> somePrivateFunction( Foo * obj )</code><br />
<code class="macmade-source">{</code><br />
<code class="macmade-source">	/* Appel d'une méthode de la classe */</code><br />
<code class="macmade-source">	[ obj <span class="macmade-code-ctag">someOtherMethod</span> ];</code><br />
<code class="macmade-source">	</code><br />
<code class="macmade-source">	/* Accès à une variable d'instance de la classe */</code><br />
<code class="macmade-source">	obj-><span class="macmade-code-ctag">someInstanceVariable</span> = <span class="macmade-code-keyword">NULL</span>;</code><br />
<code class="macmade-source">}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )somePublicMethod</code><br />
<code class="macmade-source">{</code><br />
<code class="macmade-source">	<span class="macmade-code-ctag">somePrivateFunction</span>( <span class="macmade-code-keyword">self</span> );</code><br />
<code class="macmade-source">}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code>
</div>
<div>
Une instance d&#8217;une classe est tout simplement (ou presque) un pointeur vers une structure C. L&#8217;opérateur &#8216;->&#8217; peut donc parfaitement être utilisé pour accéder à une variable d&#8217;instance, qui n&#8217;est autre qu&#8217;un membre de cette structure.
</div>
<h2>Solution 3 &#8211; Catégories</h2>
<div>
Une dernière solution, sans doute la plus propre, consiste à utiliser des catégories. Ces dernières sont utilisées pour ajouter des méthodes dans une classe existante.
</div>
<div>
Par exemple:
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-keyword">@interface</span> Foo: NSObject</code><br />
<code class="macmade-source">{}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )somePublicMethod;</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@interface</span> Foo( private )</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )somePrivateMethod;</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> Foo</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> ) somePublicMethod</code><br />
<code class="macmade-source">{</code><br />
<code class="macmade-source">	[ <span class="macmade-code-keyword">self</span> <span class="macmade-code-ctag">somePrivateMethod</span> ];</code><br />
<code class="macmade-source">}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> Foo( private )</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> ) somePrivateMethod</code><br />
<code class="macmade-source">{}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code>
</div>
<div>
Ici, nous définissons l&#8217;interface de la classe Foo, ainsi qu&#8217;une catégorie nommée &#8220;private&#8221; (ce nom peut être n&#8217;importe lequel).<br />
Nous avons donc ensuite deux implémentations. Une pour les méthodes publiques, et l&#8217;autre pour les privées.<br />
Au niveau des headers, seule l&#8217;interface de base doit être présente, bien évidemment. La déclaration de la catégorie doit se faire dans le fichier contenant l&#8217;implémentation.
</div>
<div>
Il est à noter qu&#8217;il est également possible avec ce système d&#8217;utiliser une seule et unique implémentation. Pour ce faire, il suffit de déclarer une catégorie sans nom:
</div>
<div class="macmade-code">
<code class="macmade-source"><span class="macmade-code-keyword">@interface</span> Foo: NSObject</code><br />
<code class="macmade-source">{}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )somePublicMethod;</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@interface</span> Foo()</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )somePrivateMethod;</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> Foo</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> ) somePublicMethod</code><br />
<code class="macmade-source">{</code><br />
<code class="macmade-source">	[ <span class="macmade-code-keyword">self</span> <span class="macmade-code-ctag">somePrivateMethod</span> ];</code><br />
<code class="macmade-source">}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> ) somePrivateMethod</code><br />
<code class="macmade-source">{}</code><br />
<code class="macmade-source"></code><br />
<code class="macmade-source"><span class="macmade-code-keyword">@end</span></code>
</div>
<div>
Dès lors, puisque les méthodes privées sont définies dans la catégorie, leur ordre de déclaration dans l&#8217;implémentation n&#8217;a plus aucune importance, contrairement à la première solution présentée ici.
</div>
<h2>Quelle solution choisir?</h2>
<div>
Ces trois solutions fonctionnent très bien. Personnellement, j&#8217;ai tendance à éviter la première, principalement en raison de l&#8217;ordre de déclaration, et aussi parce que les méthodes privées sont difficilement repérables dans le code.<br />
L&#8217;utilisation de catégories permet au code de rester clair et lisible, l&#8217;implémentation des méthodes privées pouvant se faire dans un autre fichier que l&#8217;implémentation des méthodes publiques. Cela permet du coup d&#8217;identifier immédiatement la visibilité d&#8217;une méthode.
</div>
<div>
C&#8217;est donc cette troisième solution que je préconise, est qui certainement la plus adaptée au langage Objective-C.
</div>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2010/03/04/methodes-privees-en-objective-c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Réseaux sociaux et bonnes pratiques</title>
		<link>http://blog.netinfluence.com/2010/01/19/reseaux-sociaux-et-bonnes-pratiques/</link>
		<comments>http://blog.netinfluence.com/2010/01/19/reseaux-sociaux-et-bonnes-pratiques/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 11:05:07 +0000</pubDate>
		<dc:creator>sandrine</dc:creator>
				<category><![CDATA[reach]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[conseils]]></category>
		<category><![CDATA[Réseaux sociaux]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=769</guid>
		<description><![CDATA[Comment faire pour être présent sans ruiner sa réputation, ne pas y perdre trop de temps, suivre ses amis et développer de chaleureuses et constructives relations online ? C&#8217;est un savant mélange de naturel et de discipline et de beaucoup de bon sens selon moi.  Voici les conseils que j&#8217;ai pu donner lors de mon interview par le Migros Magazine.]]></description>
			<content:encoded><![CDATA[<p>Comment faire pour être présent sans ruiner sa réputation, ne pas y perdre trop de temps, suivre ses amis et développer de chaleureuses et constructives relations online ? C&#8217;est un savant mélange de naturel et de discipline et de beaucoup de bon sens selon moi.  Voici les conseils que j&#8217;ai pu donner lors de mon <a title="Réseaux sociaux et bonnes pratiques par Migros" href="http://www.migrosmagazine.ch/index.cfm?id=26774" target="_blank">interview par le Migros Magazine</a>.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2010/01/19/reseaux-sociaux-et-bonnes-pratiques/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Closure et fonctions lambda en Objective-C</title>
		<link>http://blog.netinfluence.com/2009/11/12/closure-et-fonctions-lambda-en-objective-c/</link>
		<comments>http://blog.netinfluence.com/2009/11/12/closure-et-fonctions-lambda-en-objective-c/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 22:02:00 +0000</pubDate>
		<dc:creator>macmade</dc:creator>
				<category><![CDATA[create]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[avant-garde]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[communauté]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[méthodes]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[XCode]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=55</guid>
		<description><![CDATA[De nombreux langages de scripts permettent l'utilisation de «fonctions lambdas», ou encore «fonctions anonymes», concept généralement lié au phénomène appelé «closure».<br />
 Il s'agit de concepts bien connus notamment en JavaScript, ActionScript, ou encore en PHP depuis sa version 5.3.<br />
 Le langage Objective-C offre depuis peu une implémentation de ces deux concepts, appelée «blocks».<br />
 Les blocks sont disponibles depuis Mac OS X 10.6 et l'adoption de Clang.]]></description>
			<content:encoded><![CDATA[<div class="macmade-grey">
<div class="macmade-small"> Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be found at: <a href="http://www.gnu.org/copyleft/fdl.html" title="Free Documentation License">http://www.gnu.org/copyleft/fdl.html</a></div>
</div>
<h3>Définitions</h3>
<div>
De nombreux langages de scripts permettent l&#8217;utilisation de «fonctions lambdas», ou encore «fonctions anonymes», concept généralement lié au phénomène appelé «closure».<br />
 Il s&#8217;agit de concepts bien connus notamment en JavaScript, ActionScript, ou encore en PHP depuis sa version 5.3.<br />
 Le langage Objective-C offre depuis peu une implémentation de ces deux concepts, appelée «blocks».<br />
 Les blocks sont disponibles depuis Mac OS X 10.6 et l&#8217;adoption de Clang.
</div>
<p><span id="more-55"></span></p>
<h4>Fonctions anonymes</h4>
<div> Comme son nom l&#8217;indique, une fonction anonyme est une fonction ne possédant pas de nom, ou d&#8217;identifiant. Elle ne contient que son contenu (body), et peut être associée à une variable, pour être ré-utilisée, ou passée en argument d&#8217;une autre fonction. </div>
<div> Ce phénomène est très souvent utilisé dans des langages de scripts, notamment pour des callbacks. </div>
<div> En JavaScript par exemple, imaginons une fonction standard nommée «foo», prenant en paramètre un callback, et l&#8217;exécutant dans son body: </div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-keyword">function</span> foo( callback )</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    callback();</code><br />
 <code class="macmade-source">}</code> </div>
<div> Il est parfaitement possible de définir une autre fonction standard, et de la passer en paramètre de notre première fonction: </div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-keyword">function</span> bar()</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    alert( <span class="macmade-code-string">'Hello World!'</span> );</code><br />
 <code class="macmade-source">}</code></p>
<p> <code class="macmade-source">foo( bar );</code> </div>
<div> Le problème dans un tel cas est que nous déclarons une fonction nommée «bar» dans le scope global. Il en découle un risque de collision avec une éventuelle autre fonction qui porterait le même nom. </div>
<div> Le langage JavaScript nous permet donc de déclarer la fonction utilisée comme callback lors de l&#8217;appel: </div>
<div class="macmade-code"> <code class="macmade-source">foo(</code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">function</span>()</code><br />
 <code class="macmade-source">    {</code><br />
 <code class="macmade-source">        alert( <span class="macmade-code-string">'Hello World!'</span> );</code><br />
 <code class="macmade-source">    }</code><br />
 <code class="macmade-source">);</code> </div>
<div> Notre callback n&#8217;a ici pas d&#8217;identifiant. Il n&#8217;existera pas dans le scope global, et donc ne risquera pas d&#8217;entrer en conflit avec une fonction existante. </div>
<div> Il est également possible de définir le callback comme variable. Il n&#8217;existera toujours pas dans le scope global, mais pourra ainsi être ré-utilisé à volonté via cette variable: </div>
<div class="macmade-code"> <code class="macmade-source">myCallback = <span class="macmade-code-keyword">function</span>()</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    alert( <span class="macmade-code-string">'Hello World!'</span> );</code><br />
 <code class="macmade-source">};</code></p>
<p> <code class="macmade-source">foo( myCallback );</code> </div>
<h4>Closure</h4>
<div> Le phénomène appelé «closure» consiste en la possibilité, pour une fonction, d&#8217;accéder aux variables disponibles dans son contexte de déclaration, ceci même dans le cas où son contexte d&#8217;exécution est différent. </div>
<div> Toujours en JavaScript, imaginons le code suivant: </div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-keyword">function</span> foo( callback )</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    alert( callback() );</code><br />
 <code class="macmade-source">}</code></p>
<p> <code class="macmade-source"><span class="macmade-code-keyword">function</span> bar()</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">var</span> str = <span class="macmade-code-string">'Hello World'</span>;</code></p>
<p> <code class="macmade-source">    foo(</code><br />
 <code class="macmade-source">        <span class="macmade-code-keyword">function</span>()</code><br />
 <code class="macmade-source">        {</code><br />
 <code class="macmade-source">            <span class="macmade-code-keyword">return</span> str;</code><br />
 <code class="macmade-source">        }</code><br />
 <code class="macmade-source">    );</code><br />
 <code class="macmade-source">}</code></p>
<p> <code class="macmade-source">bar();</code> </div>
<div> Notre callback, passé à la fonction «foo» depuis le contexte d&#8217;exécution de le fonction «bar» retourne une variable nommée «str».<br />
 Or, cette variable, déclarée dans le contexte de la fonction «bar», est une variable locale à cette dernière. Autrement dit, elle n&#8217;existe qu&#8217;à l&#8217;intérieur de ce contexte.<br />
 Comme notre callback est exécuté depuis un contexte différent du contexte de la déclaration de cette variable, on pourrait penser que le code-ci dessus n&#8217;affiche rien.<br />
 Mais c&#8217;est ici que le phénomène de closure intervient.<br />
 Quel que soit son contexte d&#8217;exécution, une fonction conserve un accès aux variables disponibles lors de sa déclaration. </div>
<div> Notre callback aura donc bien accès à la variable «str», même s&#8217;il est effectivement appelé depuis la fonction «foo», et que cette dernière n&#8217;y a pas accès. </div>
<h3>Implémentation en Objective-C</h3>
<div> Objective-C implémente ce genre de concepts, même s&#8217;il existe un certain nombre de subtilités, venant du fait qu&#8217;il s&#8217;agit d&#8217;un langage compilé dérivé du C, en restant très proche, donc très différent d&#8217;un langage de script interprété. </div>
<div> Il est à noter que le support des blocks est aussi disponible en C pur, ou en C++ (et donc en Objective-C++). </div>
<div> De même qu&#8217;une fonction standard en C, la déclaration d&#8217;un block (fonction anonyme) se doit d&#8217;être précédée par la déclaration de son prototype. </div>
<div> La syntaxe de déclaration d&#8217;un block n&#8217;est pas la plus évidente, mais on s&#8217;y fait relativement vite.<br />
 Voici par exemple le prototype d&#8217;un block: </div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-predefined">NSString</span> * ( ^myBlock )( <span class="macmade-code-keyword">int</span> );</code> </div>
<div> Nous déclarons ici le prototype d&#8217;un block («^»), destiné à être nommé «myBlock», prenant un argument unique de type «int», et retournant un pointeur sur un objet de type «NSString». </div>
<div> Nous pouvons maintenant déclarer le block: </div>
<div class="macmade-code"> <code class="macmade-source">myBlock = ^( <span class="macmade-code-keyword">int</span> number )</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">return</span> [ <span class="macmade-code-predefined">NSString stringWithFormat</span>: <span class="macmade-code-string">@"Passed number: %i"</span>, number ];</code><br />
 <code class="macmade-source">};</code> </div>
<div> Nous assignons donc à la variable «myBlock» le body d&#8217;une fonction, prenant comme argument «number» un entier. Cette fonction retourne un objet «NSString», dans lequel sera affiché cet entier. </div>
<div> <strong>Attention, ne pas oublier le point virgule à la fin de la déclaration du block!</strong> </div>
<div> Si cela est facultatif dans des langages de scripts, c&#8217;est absolument nécessaire pour un langage compilé comme Objective-C.<br />
 L&#8217;oublier résulterait en une erreur du compilateur, qui refuserait de générer l&#8217;exécutable final. </div>
<div> Le block peut désormais être utilisé, comme une fonction standard: </div>
<div class="macmade-code"> <code class="macmade-source">myBlock();</code> </div>
<div> Voici le code complet d&#8217;un programme Objective-C, reprenant l&#8217;exemple précédent: </div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-keyword">#import</span> <span class="macmade-code-string">&lt;Cocoa/Cocoa.h&gt;</span></code></p>
<p> <code class="macmade-source"><span class="macmade-code-keyword">int</span> main( <span class="macmade-code-keyword">void</span> )</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    <span class="macmade-code-predefined">NSAutoreleasePool</span> * pool;</code><br />
 <code class="macmade-source">    <span class="macmade-code-predefined">NSString</span>          * ( ^myBlock )( <span class="macmade-code-keyword">int</span> );</code></p>
<p> <code class="macmade-source">    pool    = [ [ <span class="macmade-code-predefined">NSAutoreleasePool</span> alloc ] init ];</code><br />
 <code class="macmade-source">    myBlock = ^( <span class="macmade-code-keyword">int</span> number )</code><br />
 <code class="macmade-source">    {</code><br />
 <code class="macmade-source">        <span class="macmade-code-keyword">return</span> [ <span class="macmade-code-predefined">NSString stringWithFormat</span>: <span class="macmade-code-string">@"Passed number: %i"</span>, number ];</code><br />
 <code class="macmade-source">    };</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-predefined">NSLog</span>( <span class="macmade-code-string">@"%@"</span>, myBlock() );</code></p>
<p> <code class="macmade-source">    [ pool release ];</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-keyword">return</span> EXIT_SUCCESS;</code><br />
 <code class="macmade-source">}</code> </div>
<div> Un tel programme peut être compilé à l&#8217;aide de la commande suivante (Terminal): </div>
<div class="macmade-code"> <code class="macmade-source">gcc -Wall -framework Cocoa -o test test.m</code> </div>
<div> Cela générera un fichier exécutable nommé «test», à partir du fichier source «test.m».<br />
 Pour lancer l&#8217;exécutable: </div>
<div class="macmade-code"> <code class="macmade-source">./test</code> </div>
<div> La déclaration du prototype d&#8217;un block peut être omise dans le cas où le block n&#8217;est pas assigné à une variable, comme par exemple s&#8217;il est transmis directement comme argument. </div>
<div> Par exemple: </div>
<div class="macmade-code"> <code class="macmade-source">someFunction( ^ <span class="macmade-code-predefined">NSString</span> * ( <span class="macmade-code-keyword">void</span> ) { <span class="macmade-code-keyword">return</span> <span class="macmade-code-string">@"Hello World!"</span> } );</code> </div>
<div> Il est à noter que dans un tel cas, le type de retour doit être déclaré. Ici, il s&#8217;agit d&#8217;un objet de type «NSString». </div>
<h4>Passage d&#8217;un block comme argument</h4>
<div> Un block peut bien sûr être passé comme argument d&#8217;une fonction C.<br />
 Là aussi, la syntaxe peut être quelque peu déroutante à première vue: </div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-keyword">void</span> logBlock( <span class="macmade-code-predefined">NSString</span> * ( ^theBlock )( <span class="macmade-code-keyword">int</span> ) )</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    <span class="macmade-code-predefined">NSLog</span>( <span class="macmade-code-string">@"Block returned: %@"</span>, theBlock() );</code><br />
 <code class="macmade-source">}</code> </div>
<div> Evidemment, comme Objective-C est un langage fortement typé, une fonction recevant un block en argument doit également déclarer son type de retour et le type de ses éventuels arguments. </div>
<div> Il en va de même dans le cas d&#8217;une méthode d&#8217;une classe Objective-C: </div>
<div class="macmade-code"> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )logBlock: ( <span class="macmade-code-predefined">NSString</span> * ( ^ )( <span class="macmade-code-keyword">int</span> ) )theBlock;</code> </div>
<h4>Closure</h4>
<div> Le phénomène de closure est également présent en Objective-C, même si son comportement est évidemment différent de celui des langages interprétés. </div>
<div> Imaginons le programme suivant: </div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-keyword">#import</span> <span class="macmade-code-string">&lt;Cocoa/Cocoa.h&gt;</span></code></p>
<p> <code class="macmade-source"><span class="macmade-code-keyword">void</span> logBlock( <span class="macmade-code-keyword">int</span> ( ^theBlock )( <span class="macmade-code-keyword">void</span> ) )</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    <span class="macmade-code-predefined">NSLog</span>( <span class="macmade-code-string">@"Closure var X: %i"</span>, theBlock() );</code><br />
 <code class="macmade-source">}</code></p>
<p> <code class="macmade-source"><span class="macmade-code-keyword">int</span> main( <span class="macmade-code-keyword">void</span> )</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    <span class="macmade-code-predefined">NSAutoreleasePool</span> * pool;</code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">int</span> ( ^myBlock )( <span class="macmade-code-keyword">void</span> );</code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">int</span> x;</code></p>
<p> <code class="macmade-source">    pool = [ [ <span class="macmade-code-predefined">NSAutoreleasePool</span> alloc ] init ];</code><br />
 <code class="macmade-source">    x    = 27;</code></p>
<p> <code class="macmade-source">    myBlock = ^( <span class="macmade-code-keyword">void</span> )</code><br />
 <code class="macmade-source">    {</code><br />
 <code class="macmade-source">        <span class="macmade-code-keyword">return</span> x;</code><br />
 <code class="macmade-source">    };</code></p>
<p> <code class="macmade-source">    logBlock( myBlock );</code></p>
<p> <code class="macmade-source">    [ pool release ];</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-keyword">return</span> EXIT_SUCCESS;</code><br />
 <code class="macmade-source">}</code> </div>
<div> La fonction «main» déclare un entier, de valeur 27, ainsi qu&#8217;un block, retournant cette même variable.<br />
 Le block set ensuite passé à la fonction «logBlock», qui affiche sa valeur de retour. </div>
<div> Même dans le contexte d&#8217;exécution de la fonction «logBlock», le block déclaré dans la fonction «main» continue d&#8217;avoir accès à l&#8217;entier «x», et peut donc sans aucun problème en retourner la valeur. </div>
<div> Il est à noter que les blocks ont également accès aux variable globales, même statiques si elles sont disponibles dans le contexte du block. </div>
<div> Il existe ici une première subtilité. En effet, les variables disponibles depuis un block par le phénomène de closure sont de type «const». Autrement dit, elle ne peuvent être modifiées depuis l&#8217;intérieur du block. </div>
<div> Par exemple, imaginons que notre block incrémente la valeur de x avant de la retourner: </div>
<div class="macmade-code"> <code class="macmade-source">myBlock = ^( <span class="macmade-code-keyword">void</span> )</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    x++</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-keyword">return</span> x;</code><br />
 <code class="macmade-source">};</code> </div>
<div> Le compilateur refusera ici de compiler le programme, puisque la variable «x» n&#8217;est disponible qu&#8217;en lecture pour notre block. </div>
<div> Pour qu&#8217;une variable puisse être modifiée depuis un block, il faut la déclarer avec le mot clé «__block».<br />
 Ainsi, le codé précédent est valide si l&#8217;on déclare la variable x ainsi: </div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-keyword">__block</span> <span class="macmade-code-keyword">int</span> x;</code> </div>
<h4>Gestion de la mémoire</h4>
<div> Au niveau C, un block est une structure, pouvant être copiée et détruite.<br />
 Deux fonctions C sont à disposition pour cet usage: «Block_copy()» et «Block_destroy».<br />
 En Objective-C, un block peut également recevoir les messages «retain», «release» et «copie», comme un objet. </div>
<div> C&#8217;est aspect peut-être extrêmement important dans le cas où un block doit être conservé pour une utilisation ultérieure (et par exemple stocké dans une propriété d&#8217;une classe). </div>
<div> Ne pas copier le block, ou ne pas effectuer de «retain» dans un tel cas peut en effet induire une erreur de segmentation. </div>
<h4>Exemple d&#8217;utilisation</h4>
<div> Les blocks peuvent être utilisés dans de très nombreux contextes, afin de simplifier le code, et réduire le nombre de fonctions déclarées. </div>
<div> Voici un exemple simple illustrant l&#8217;utilisation des blocks. </div>
<div> Nous allons ajouter à la classe «NSArray» une méthode statique permettant de générer un tableau en filtrant les éléments d&#8217;un autre tableau, à l&#8217;aide d&#8217;un callback. </div>
<div> Pour les amateurs de PHP, il s&#8217;agit ici d&#8217;un équivalent de la fonction «array_filter()». </div>
<div> Nous allons commencer par la déclaration d&#8217;une catégorie de la classe «NSArray». Pour rappel, une catégorie permet l&#8217;ajout de méthodes dans une classe existante, évitant ainsi le besoin de créer une sous-classe.</div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-keyword">@interface</span> <span class="macmade-code-predefined">NSArray</span>( BlockExample )</code></p>
<p> <code class="macmade-source">+ ( <span class="macmade-code-predefined">NSArray</span> * )arrayByFilteringArray: ( <span class="macmade-code-predefined">NSArray</span> * )source withCallback: ( <span class="macmade-code-keyword">BOOL</span> ( ^ )( <span class="macmade-code-keyword">id</span> ) )callback;</code></p>
<p> <code class="macmade-source"><span class="macmade-code-keyword">@end</span></code> </div>
<div> Nous déclarons ici une méthode retournant un objet de type «NSArray», et prenant en argument un autre objet «NSArray», ainsi qu&#8217;un callback, sous forme de block. </div>
<div> Ce callback sera exécuté pour chaque élément du tableau passé en argument. Il doit retourner une valeur booléenne, afin de savoir si l&#8217;élément courant du tableau source doit être conservé dans le tableau retourné. Le block prend donc comme unique argument l&#8217;objet courant du tableau source. </div>
<div> Voyons maintenant l&#8217;implémentation de cette méthode: </div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> <span class="macmade-code-predefined">NSArray</span>( BlockExample )</code></p>
<p> <code class="macmade-source">+ ( <span class="macmade-code-predefined">NSArray</span> * )arrayByFilteringArray: ( <span class="macmade-code-predefined">NSArray</span> * )source withCallback: ( <span class="macmade-code-keyword">BOOL</span> ( ^ )( <span class="macmade-code-keyword">id</span> ) )callback</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    <span class="macmade-code-predefined">NSMutableArray</span> * result;</code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">id</span>               element;</code></p>
<p> <code class="macmade-source">    result = [ <span class="macmade-code-predefined">NSMutableArray</span> <span class="macmade-code-predefined">arrayWithCapacity</span>: [ source count ] ];</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-keyword">for</span>( element <span class="macmade-code-keyword">in</span> source ) {</code></p>
<p> <code class="macmade-source">        <span class="macmade-code-keyword">if</span>( callback( element ) == <span class="macmade-code-keyword">YES</span> ) {</code></p>
<p> <code class="macmade-source">            [ result <span class="macmade-code-predefined">addObject</span>: element ];</code><br />
 <code class="macmade-source">        }</code><br />
 <code class="macmade-source">    }</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-keyword">return</span> result;</code><br />
 <code class="macmade-source">}</code></p>
<p> <code class="macmade-source"><span class="macmade-code-keyword">@end</span></code> </div>
<div> Nous créons en premier lieu un tableau de taille dynamique («NSMutableArray»), en lui allouant une capacité initiale correspondant au nombre d&#8217;entrées du tableau source. </div>
<div> Ensuite, nous itérons chaque élément du tableau source, et nous ajoutons l&#8217;élément courant dans le cas où le résultat du callback retourne la valeur booléenne «YES». </div>
<div> Voici un exemple de programme utilisant une telle méthode.<br />
 Ici, nous nous servons du callback pour créer un tableau ne contenant que les objets de type «NSString» du tableau source: </div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-keyword">#import</span> <span class="macmade-code-string">&lt;Cocoa/Cocoa.h&gt;</span></code></p>
<p> <code class="macmade-source"><span class="macmade-code-keyword">@interface</span> <span class="macmade-code-predefined">NSArray</span>( BlockExample )</code></p>
<p> <code class="macmade-source">+ ( <span class="macmade-code-predefined">NSArray</span> * )arrayByFilteringArray: ( <span class="macmade-code-predefined">NSArray</span> * )source withCallback: ( <span class="macmade-code-keyword">BOOL</span> ( ^ )( <span class="macmade-code-keyword">id</span> ) )callback;</code></p>
<p> <code class="macmade-source"><span class="macmade-code-keyword">@end</span></code></p>
<p> <code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> <span class="macmade-code-predefined">NSArray</span>( BlockExample )</code></p>
<p> <code class="macmade-source">+ ( <span class="macmade-code-predefined">NSArray</span> * )arrayByFilteringArray: ( <span class="macmade-code-predefined">NSArray</span> * )source withCallback: ( <span class="macmade-code-keyword">BOOL</span> ( ^ )( <span class="macmade-code-keyword">id</span> ) )callback</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    <span class="macmade-code-predefined">NSMutableArray</span> * result;</code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">id</span>               element;</code></p>
<p> <code class="macmade-source">    result = [ <span class="macmade-code-predefined">NSMutableArray</span> <span class="macmade-code-predefined">arrayWithCapacity</span>: [ source count ] ];</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-keyword">for</span>( element <span class="macmade-code-keyword">in</span> source ) {</code></p>
<p> <code class="macmade-source">        <span class="macmade-code-keyword">if</span>( callback( element ) == <span class="macmade-code-keyword">YES</span> ) {</code></p>
<p> <code class="macmade-source">            [ result <span class="macmade-code-predefined">addObject</span>: element ];</code><br />
 <code class="macmade-source">        }</code><br />
 <code class="macmade-source">    }</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-keyword">return</span> result;</code><br />
 <code class="macmade-source">}</code></p>
<p> <code class="macmade-source"><span class="macmade-code-keyword">@end</span></code></p>
<p> <code class="macmade-source"><span class="macmade-code-keyword">int</span> main( <span class="macmade-code-keyword">void</span> )</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    <span class="macmade-code-predefined">NSAutoreleasePool</span> * pool;</code><br />
 <code class="macmade-source">    <span class="macmade-code-predefined">NSArray</span>           * array1;</code><br />
 <code class="macmade-source">    <span class="macmade-code-predefined">NSArray</span>           * array2;</code></p>
<p> <code class="macmade-source">    pool   = [ [ <span class="macmade-code-predefined">NSAutoreleasePool</span> alloc ] init ];</code><br />
 <code class="macmade-source">    array1 = [ <span class="macmade-code-predefined">NSArray</span> <span class="macmade-code-predefined">arrayWithObjects</span>: <span class="macmade-code-string">@"Hello World!"</span>, [ <span class="macmade-code-predefined">NSDate</span> date ], <span class="macmade-code-string">@"Hello Universe!"</span>, <span class="macmade-code-keyword">nil</span> ];</code><br />
 <code class="macmade-source">    array2 = [ <span class="macmade-code-predefined">NSArray</span></code><br />
 <code class="macmade-source">                    <span class="macmade-code-ctag">arrayByFilteringArray</span>: array1</code><br />
 <code class="macmade-source">                    <span class="macmade-code-ctag">withCallback</span>: ^ <span class="macmade-code-keyword">BOOL</span> ( <span class="macmade-code-keyword">id</span> element )</code><br />
 <code class="macmade-source">                    {</code><br />
 <code class="macmade-source">                        <span class="macmade-code-keyword">return</span> [ element <span class="macmade-code-predefined">isKindOfClass</span>: [ <span class="macmade-code-predefined">NSString</span> class ] ];</code><br />
 <code class="macmade-source">                    }</code><br />
 <code class="macmade-source">             ];</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-predefined">NSLog</span>( <span class="macmade-code-string">@"%@"</span>, array2 );</code></p>
<p> <code class="macmade-source">    [ pool release ];</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-keyword">return</span> EXIT_SUCCESS;</code><br />
 <code class="macmade-source">}</code></div>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2009/11/12/closure-et-fonctions-lambda-en-objective-c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Implémentation d’un système de délégation multiple en Objective-C</title>
		<link>http://blog.netinfluence.com/2009/08/24/implementation-d-un-systeme-de-delegation-multiple-en-objective-c/</link>
		<comments>http://blog.netinfluence.com/2009/08/24/implementation-d-un-systeme-de-delegation-multiple-en-objective-c/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 17:24:00 +0000</pubDate>
		<dc:creator>macmade</dc:creator>
				<category><![CDATA[create]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[tutoriel]]></category>
		<category><![CDATA[wwdc]]></category>
		<category><![CDATA[XCode]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=50</guid>
		<description><![CDATA[<p>La délégation est un système présent dans plusieurs classes du framework Cocoa, sous Mac OS X (et donc également sur iPhone OS).<br />
 Ce système permet aux dévelopeurs d'applications Cocoa d'interagir en fonction d'événement précis liés aux fonctionnements intrinsèques des objets Cocoa.</p> <p>De base, le système de délégation ne peut prendre en charge qu'un objet unique. Cet article montre comment implémenter une chaine de délégation dans une classe Objective-C.</p>]]></description>
			<content:encoded><![CDATA[<div class="macmade-grey">
<div class="macmade-small">Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be found at: <a title="Free Documentation License" href="http://www.gnu.org/copyleft/fdl.html">http://www.gnu.org/copyleft/fdl.html</a></div>
</div>
<h3>1. Qu&#8217;est-ce que la délégation?</h3>
<div>La délégation est un système présent dans plusieurs classes du framework Cocoa, sous Mac OS X (et donc également sur iPhone OS).<br />
Ce système permet aux dévelopeurs d&#8217;applications Cocoa d&#8217;interagir en fonction d&#8217;événement précis liés aux fonctionnements intrinsèques des objets Cocoa.</div>
<div>Prenons par exemple l&#8217;objet NSWindow, qui comme son nom l&#8217;indique permet d&#8217;afficher et de contrôler une fenêtre.</div>
<div>Cet objet fenêtre possède un certain nombre de méthode, comme par exemple &#8216;close&#8217;, ou &#8216;open&#8217;, permettant respectivement d&#8217;ouvrir et de fermer le fenêtre en question.</div>
<div>Lors de la programmation d&#8217;une application Cocoa, il peut être fort utile d&#8217;être informé lors de l&#8217;ouverture ou de la fermeture d&#8217;une fenêtre, pour allouer ou libérer des ressources, terminer des tâches ou des threads, etc.</div>
<div>Le système de délégation du framework Cocoa permet ainsi d&#8217;attacher une instance d&#8217;un objet à un autre objet, le premier ayant la possibilité d&#8217;agir sur le second en fonction de ses différentes phases d&#8217;exécution.</div>
<div>La définition d&#8217;un objet délégué sur un autre objet se passe par convention par la méthode &#8216;setDelegate&#8217;, prenant en argument unique l&#8217;instance du délégué.</div>
<div>Par exemple, pour définir un objet de type &#8216;Foo&#8217; comme délégué d&#8217;un objet NSWindow:</div>
<div class="macmade-code"><code class="macmade-source">Foo      * foo    = [ [ Foo alloc ] init ];<br />
</code> <code class="macmade-source"><span class="macmade-code-predefined">NSWindow</span> * window = [ [ <span class="macmade-code-predefined">NSWindow</span> alloc ] <span class="macmade-code-predefined">initWithContentRect</span>: <span class="macmade-code-predefined">NSMakeRect</span>( 0, 0, 100, 100 ) <span class="macmade-code-predefined">styleMask</span>: <span class="macmade-code-predefined">NSTitledWindowMask</span> <span class="macmade-code-predefined">backing</span>: <span class="macmade-code-predefined">NSBackingStoreBuffered</span> <span class="macmade-code-predefined">defer</span>: <span class="macmade-code-keyword">NO</span> ];<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">[ window <span class="macmade-code-predefined">setDelegate</span>: foo ];</code></div>
<div>Les deux premières lignes créent respectivement un objet de type &#8216;Foo&#8217; (défini dans notre application), et un objet de type &#8216;NSWindow&#8217; (du framework Cocoa).</div>
<div>La troisième ligne défini l&#8217;objet de type &#8216;Foo&#8217; comme délégué de notre objet &#8216;NSWindow&#8217;.</div>
<div>A partir de ce moment, à supposer que l&#8217;on ferme notre objet fenêtre:</div>
<div class="macmade-code"><code class="macmade-source">[ window close ];</code></div>
<div>L&#8217;objet délégué pourra être averti de cette opération, en implémentant tout simplement une méthode spécifique. Dans le cas précis, &#8216;windowWillClose&#8217;, dont voici le prototype:</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )windowWillClose: ( <span class="macmade-code-predefined">NSNotification</span> * )notification;</code></div>
<div>Celle-ci permettra au délégué, juste avant la fermeture de la fenêtre, d&#8217;effectuer un certain nombre d&#8217;opérations, liées au bon fonctionnement de l&#8217;application.</div>
<h3>2. Comment fonctionne la délégation?</h3>
<div>Voyons maintenant comment l&#8217;objet &#8216;NSWIndow&#8217; implémente et utilise son objet délégué.</div>
<div>L&#8217;objet &#8216;NSWindow&#8217; contient bien sûr une variable d&#8217;instance de type &#8216;id&#8217;, représentant l&#8217;objet délégué, généralement nommée delegate, ainsi qu&#8217;une méthode permettant d&#8217;obtenir l&#8217;objet délégué, et une seconde permettant de le définir.</div>
<div>Autrement dit:</div>
<div class="macmade-code"><code class="macmade-source"><span class="macmade-code-keyword">@interface</span> <span class="macmade-code-predefined">NSWindow</span>: <span class="macmade-code-predefined">NSObject</span><br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@protected</span><br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">id</span> <span class="macmade-code-ctag">delegate</span>;<br />
</code> <code class="macmade-source">}<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">id</span> )delegate;<br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )setDelegate: ( <span class="macmade-code-keyword">id</span> )object;<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@end</span><br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> <span class="macmade-code-predefined">NSWindow</span><br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">id</span> )delegate<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span> <span class="macmade-code-ctag">delegate</span>;<br />
</code> <code class="macmade-source">}<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )setDelegate: ( <span class="macmade-code-keyword">id</span> )object<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-ctag">delegate</span> = object;<br />
</code> <code class="macmade-source">}<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@end</span></code></div>
<div>Ici, il est extrêmement important de préciser qu&#8217;un objet ne doit en aucun cas effectuer un &#8216;retain&#8217; sur son objet délégué, car cela aurait comme effet un &#8216;memory leak&#8217;, autrement dit une zone de mémoire allouée à notre application qui ne serait jamais libérée.</div>
<div>Il est également à noter qu&#8217;en Objective-C 2.0, l&#8217;utilisation d&#8217;une propriété peut être utilisée dans l&#8217;interface, pour permettre un accès aisé à l&#8217;objet délégué:</div>
<div class="macmade-code"><code class="macmade-source"><span class="macmade-code-keyword">@property</span>( <span class="macmade-code-keyword">nonatomic</span>, <span class="macmade-code-keyword">assign</span>, <span class="macmade-code-keyword">readwrite</span> ) <span class="macmade-code-ctag">delegate</span>;</code></div>
<div>A partir de là, les getter/setter peuvent également être automatiquement délcarés dans l&#8217;implémentation:</div>
<div class="macmade-code"><code class="macmade-source"><span class="macmade-code-keyword">@synthesize</span> delegate;</code></div>
<div>Si l&#8217;on reprend maintenant l&#8217;exemple de la méthode &#8216;close&#8217; de l&#8217;objet &#8216;NSWindow&#8217;:</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )close<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-comment">// Do something...</span><br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( [ <span class="macmade-code-ctag">delegate</span> <span class="macmade-code-predefined">respondsToSelector</span>: <span class="macmade-code-keyword">@selector</span>( windowWillClose ) ] ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> [ <span class="macmade-code-ctag">delegate</span> windowWillClose ];<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-comment">// Do something...</span><br />
</code> <code class="macmade-source">}</code></div>
<div>A un instant précis dans l&#8217;exécution de la méthode &#8216;close&#8217;, l&#8217;objet &#8216;NSWindow&#8217; se demande si son objet délégué possède une méthode nommée &#8216;windowWillClose&#8217;.<br />
Si c&#8217;est le cas, elle l&#8217;exécute, et poursuit sa propre exécution.</div>
<div>La méthode &#8216;close&#8217; n&#8217;a nullement besoin de vérifier si un objet délégué a été défini auparavant, étant donné qu&#8217;en Objective-C, envoyer un message (appeler une méthode) sur &#8216;nil&#8217; (un pointeur NULL sur un objet) est parfaitement valide.</div>
<div>L&#8217;objet délégué sera donc averti, à supposer qu&#8217;il implémente la méthode &#8216;windowWillClose&#8217;, de la fermeture de l&#8217;objet &#8216;NSWindow&#8217;.</div>
<h3>3. Délégation et notification</h3>
<div>Le framework Cocoa inclut également un système de notification, permettant là aussi à des objets d&#8217;être informé des stades d&#8217;exécution d&#8217;autres objets.</div>
<div>Dans notre exemple précédent, nous aurions donc aussi pu, pour être averti lors de la fermeture de la fenêtre, écrire le code suivant.</div>
<div class="macmade-code"><code class="macmade-source">[ [ <span class="macmade-code-predefined">NSNotificationCenter</span> defaultCenter ] <span class="macmade-code-predefined">addObserver</span>: foo <span class="macmade-code-predefined">selector</span>: <span class="macmade-code-keyword">@selector</span>( myObserverMethod: ) <span class="macmade-code-predefined">name:</span> <span class="macmade-code-predefined">NSWindowWillCloseNotification</span> <span class="macmade-code-predefined">object</span>: window ]:</code></div>
<div>Autrement dit, on déclare que la méthode &#8216;myObserverMethod&#8217; de l&#8217;objet de type &#8216;Foo&#8217; doit être lancée lors de l&#8217;événement &#8216;NSWindowWillCloseNotification&#8217; de la fenêtre. Dans ce cas, voici le prototype de la méthode &#8216;myObserverMethod&#8217;:</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )myObserverMethod: ( <span class="macmade-code-predefined">NSNotification</span> * )notification;</code></div>
<div>On peut donc ici se demander pourquoi ces deux systèmes cohexistent.<br />
Ce qu&#8217;il faut bien comprendre, c&#8217;est que le système de notification permet uniquement d&#8217;être averti de certains événements, alors que le système de délégation permet en plus de modifier le comportement de l&#8217;objet concerné.</div>
<div>Prenons le cas de la méthode &#8216;windowShouldClose&#8217;, pouvant être implémentée dans le délégué d&#8217;un objet &#8216;NSWindow&#8217;, et dont voici le prototype:</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-keyword">BOOL</span> )windowShouldClose: ( <span class="macmade-code-predefined">NSWindow</span> * )window;</code></div>
<div>On remarque que cette méthode retourne une valeur booléenne.</div>
<div>Si notre objet délégué implémente cette méthode, et qu&#8217;on lance la méthode &#8216;close&#8217; sur notre fenêtre, cette dernière ne se fermera effectivement que dans le cas où la méthode du délégué retourne la valeur &#8216;YES&#8217;. Dans le cas contraire, elle restera affichée sur l&#8217;écran.</div>
<div>Cela peut par exemple permettre de bloquer le processus de fermeture de la fenêtre, pour afficher un message d&#8217;alerte demandant à l&#8217;utilisateur s&#8217;il veut sauvegarder ses changements éventuels.</div>
<div>A ce moment là, c&#8217;est le délégué qui prend la responsabilité de savoir si et quand la fenêtre doit être fermée, ce qui serait évidemment impossible via le système de notification.</div>
<div>On voit donc ici bien la différence de logique entre la délégation et la notification, le premier pouvant agir sur l&#8217;objet concerné, au contraire du second.</div>
<div>Certains objets du framework Cocoa utilisent également leur délégué pour obtenir d&#8217;autre types d&#8217;informations, comme par exemple l&#8217;objet &#8216;NSBrowser&#8217; (la vue en colonne du Finder) qui utilise son délégué pour connaître les éléments à afficher.</div>
<h3>4. Chaîne de délégation</h3>
<div>A ce niveau là, on peut remarquer une certaine limitation dans le système de délégation. Un objet ne peut avoir qu&#8217;un seul et unique délégué.</div>
<div>Prenons le code suivant:</div>
<div class="macmade-code"><code class="macmade-source">[ window <span class="macmade-code-predefined">setDelegate</span>: foo ];<br />
</code> <code class="macmade-source">[ window <span class="macmade-code-predefined">setDelegate</span>: bar ];</code></div>
<div>Le délégué de l&#8217;objet &#8216;window&#8217; sera donc &#8216;bar&#8217;, qui remplacera &#8216;foo&#8217; à ce poste. L&#8217;objet &#8216;foo&#8217;, quand à lui, ne sera plus du tout en mesure de contrôler les différents aspects de la fenêtre.</div>
<div>Or il pourrait être fort utile, dans certains cas, de pouvoir placer plusieurs délégués sur un même objet. Nous allons donc implémenter un système permettant de chaîner les objet délégués.</div>
<h3>5. Implémentation &#8211; MultipleDelegateObject</h3>
<div>Nous allons tout d&#8217;abord créer un classe, qui servira de base aux classes voulant implémenter une chaîne de délégués:</div>
<div class="macmade-code"><code class="macmade-source"><span class="macmade-code-comment">/* MultipleDelegateObject.h */</span><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@interface</span> MultipleDelegateObject: <span class="macmade-code-predefined">NSObject</span><br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@protected</span><br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-ctag">DelegateChain</span> * <span class="macmade-code-ctag">delegate</span>;<br />
</code> <code class="macmade-source">}<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )addDelegate: ( <span class="macmade-code-keyword">id</span> )object;<br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )removeDelegate: ( <span class="macmade-code-keyword">id</span> )object;<br />
</code> <code class="macmade-source">- ( <span class="macmade-code-predefined"><span class="macmade-code-predefined">NSArray</span></span> * )delegates;<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@end</span>;</code></div>
<div>Nous n&#8217;allons pas gérer la chaîne de délégué dans cette objet, mais plutôt créer une seconde classe, nommée &#8216;DelegateChain&#8217;, que nous étudierons après.</div>
<div>Notre classe contient donc une méthode permettant d&#8217;ajouter un délégué, une méthode permettant d&#8217;en enlever un, et une méthode permettant d&#8217;obtenir sous forme de tableau tous les objets délégués.</div>
<div>L&#8217;implémentation est la suivante:</div>
<div class="macmade-code"><code class="macmade-source"><span class="macmade-code-comment">/* MultipleDelegateObject.m */</span><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@implementation</span><br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">id</span> )init<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( ( <span class="macmade-code-keyword">self</span> = [ <span class="macmade-code-keyword">super</span> init ] ) ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-ctag">delegate</span> = [ [ <span class="macmade-code-ctag">DelegateChain</span> alloc ] init ];<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span> <span class="macmade-code-keyword">self</span>;<br />
</code> <code class="macmade-source">}<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )dealloc<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> [ <span class="macmade-code-ctag">delegate</span> release ];<br />
</code> <code class="macmade-source"> [ <span class="macmade-code-keyword">super</span> dealloc ];<br />
</code> <code class="macmade-source">}<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )addDelegate: ( <span class="macmade-code-keyword">id</span> )object<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> [ <span class="macmade-code-ctag">delegate</span> <span class="macmade-code-ctag">addDelegate</span>: object ];<br />
</code> <code class="macmade-source">}<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )removeDelegate: ( <span class="macmade-code-keyword">id</span> )object<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> [ <span class="macmade-code-ctag">delegate</span> <span class="macmade-code-ctag">removeDelegate</span>: object ];<br />
</code> <code class="macmade-source">}<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-predefined"><span class="macmade-code-predefined">NSArray</span></span> * )delegates<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span> [ <span class="macmade-code-ctag">delegate</span> <span class="macmade-code-ctag">delegates</span> ];<br />
</code> <code class="macmade-source">}<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@end</span></code></div>
<div>La méthode &#8216;init&#8217; crée une nouvelle instance de la classe &#8216;DelegateChain&#8217;, et la stocke dans la variable d&#8217;instance &#8216;delegate&#8217;. La méthode &#8216;dealloc&#8217; libère cette resource lors de la destruction de l&#8217;objet.</div>
<div>Les trois autres méthodes ne font que re-router les appels sur l&#8217;objet de type &#8216;DelegateChain&#8217;, qui gérera elle les délégués multiples.</div>
<h3>6. Implémentation &#8211; DelegateChain</h3>
<div>Regardons maintenant l&#8217;interface de la classe &#8216;DelegateChain&#8217;:</div>
<div class="macmade-code"><code class="macmade-source"><span class="macmade-code-comment">/* DelegateChain.h */</span><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@interface</span> DelegateChain: <span class="macmade-code-predefined">NSObject</span><br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@protected</span><br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">id</span> * <span class="macmade-code-ctag">delegates</span>;<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSUInteger</span> <span class="macmade-code-ctag">numberOfDelegates</span>;<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSUInteger</span> <span class="macmade-code-ctag">sizeOfDelegatesArray</span>;<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSMutableDictionary</span> * <span class="macmade-code-ctag">hashs</span>;<br />
</code> <code class="macmade-source">}<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )addDelegate: ( <span class="macmade-code-keyword">id</span> )object;<br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )removeDelegate: ( <span class="macmade-code-keyword">id</span> )object;<br />
</code> <code class="macmade-source">- ( <span class="macmade-code-predefined">NSArray</span> * )delegates;<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@end</span></code></div>
<div>Comme précisé auparavant, il ne faut pas effectuer de &#8216;retain&#8217; sur les objets délégués. Il nous est donc impossible d&#8217;utiliser un objet de type &#8216;NSMutableArray&#8217; ou &#8216;NSMutableDictionary&#8217; pour stocker les délégués, car ceci aurait pour effet un &#8216;retain&#8217; automatique lors de l&#8217;ajout.</div>
<div>Un tableau de pointeur sur les délégués (le type &#8216;id&#8217; est en fait un pointeur), alloué et ré-alloué si nécessaire avec les fonctions d&#8217;allocation de mémoire de la bibliothèque standard C, fera par contre très bien l&#8217;affaire. Il s&#8217;agit dans notre cas de la variable d&#8217;instance &#8216;delegates&#8217;.</div>
<div>Nous avons également une variable contenant le nombre de délégués actuellement affectés (&#8216;numberOfDelegates&#8217;), et une autre (&#8216;sizeOfDelegatesArray&#8217;) contenant la taille du tableau de pointeur précédemment cité, et dont nous verrons l&#8217;utilité plus tard.</div>
<div>La variable &#8216;hash&#8217;, quand à elle, servira à stocker les adresses mémoire des délégués, afin de trouver facilement leur position dans le tableau de pointeur.</div>
<div>Regardons maintenant, méthode par méthode, l&#8217;implémentation de la classe &#8216;DelegateChain&#8217;. En tout premier lieu, son initialisation:</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-keyword">id</span> )init<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( ( <span class="macmade-code-keyword">self</span> = [ <span class="macmade-code-keyword">super</span> init ] ) ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> hash = [ [ <span class="macmade-code-predefined">NSMutableDictionary</span> <span class="macmade-code-predefined">dictionaryWithCapacity</span>: 10 ] retain ];<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( <span class="macmade-code-keyword">NULL</span> = ( <span class="macmade-code-ctag">delegates</span> = ( <span class="macmade-code-keyword">id</span> * )<span class="macmade-code-predefined">calloc</span>( 10, <span class="macmade-code-keyword">sizeof</span>( <span class="macmade-code-keyword">id</span> ) ) ) ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-comment">// Error management...</span><br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span> <span class="macmade-code-keyword">self</span>;<br />
</code> <code class="macmade-source">}</code></div>
<div>Nous créons le dictionnaire qui nous permettra de stocker les adresses mémoire, et nous réservons une zone dans la mémoire pour stocker les pointeurs vers nos objets délégués. Nous réservons une zone pouvant contenir 10 objets, afin d&#8217;éviter d&#8217;avoir à appeler les fonctions d&#8217;allocation à chaque fois qu&#8217;un délégué est ajouté, ce qui nuirait aux performances. En cas de dépassement, nous ré-allouerons cette zone par 10.</div>
<div>Comme nous avons réservé de la mémoire, il ne faut pas oublier de la libérer lors de la destruction de l&#8217;objet:</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )dealloc<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">free</span>( <span class="macmade-code-ctag">delegates</span> );<br />
</code> <code class="macmade-source"> [ <span class="macmade-code-ctag">hashs</span> release ];<br />
</code> <code class="macmade-source"> [ <span class="macmade-code-keyword">super</span> dealloc ];<br />
</code> <code class="macmade-source">}</code></div>
<div>Regardons maintenant la méthode utilisée pour ajouter un délégué:</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )addDelegate: ( <span class="macmade-code-keyword">id</span> )object<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSString</span> * hash;<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( object == <span class="macmade-code-keyword">nil</span> ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span>;<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( <span class="macmade-code-ctag">numberOfDelegates</span> == <span class="macmade-code-ctag">sizeOfDelegatesArray</span> ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( <span class="macmade-code-keyword">NULL</span> == ( <span class="macmade-code-ctag">delegates</span> = ( <span class="macmade-code-keyword">id</span> * )<span class="macmade-code-predefined">realloc</span>( <span class="macmade-code-ctag">delegates</span>, ( <span class="macmade-code-ctag">sizeOfDelegatesArray</span> + 10 ) * <span class="macmade-code-keyword">sizeof</span>( <span class="macmade-code-keyword">id</span> ) ) ) ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-comment">// Error management...</span><br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-ctag">sizeOfDelegatesArray</span> += 10;<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> hash = [ [ <span class="macmade-code-predefined">NSNumber</span> <span class="macmade-code-predefined">numberWithUnsignedInteger</span>: ( <span class="macmade-code-predefined">NSUInteger</span> )object ] stringValue ];<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( [ <span class="macmade-code-ctag">hashs</span> <span class="macmade-code-predefined">objectForKey</span>: hash ] != <span class="macmade-code-keyword">nil</span> ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span>;<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-ctag">delegates</span>[ <span class="macmade-code-ctag">numberOfDelegates</span> ] = object;<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> [ <span class="macmade-code-ctag">hashs</span> <span class="macmade-code-predefined">setObject</span>: [ <span class="macmade-code-predefined">NSNumber</span> <span class="macmade-code-predefined">numberWithUnsignedInteger</span>: <span class="macmade-code-ctag">numberOfDelegates</span> ] <span class="macmade-code-predefined">forKey</span>: hash ];<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-ctag">numberOfDelegates</span>++;<br />
</code> <code class="macmade-source">}</code></div>
<div>Nous avons précédemment alloué un emplacement pour 10 délégués. A supposer qu&#8217;il y en ait 10, et que nous ajoutons un onzième, nous augmentons la zone mémoire de 10, grâce à la fonction &#8216;realloc&#8217;.</div>
<div>Nous prenons ensuite l&#8217;adresse mémoire de l&#8217;objet, sous forme de chaîne de charactère, et nous contrôlons que l&#8217;objet n&#8217;a pas déjà ajouté comme délégué. De cette façon, il est impossible d&#8217;ajouter plusieurs fois le même objet comme délégué.</div>
<div>Il ne nous reste plus qu&#8217;à stocker le pointeur vers notre objet, son adresse mémoire avec sa position dans le tableau de pointeur, et augmenter de 1 la variable contenant le nombre de délégués.</div>
<div>Sur le même principe, voici la fonction permettant d&#8217;enlever un délégué.</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )removeDelegate: ( <span class="macmade-code-keyword">id</span> )object<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSString</span> * hash;<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSUInteger</span> index;<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSUInteger</span> i;<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( object == <span class="macmade-code-keyword">nil</span> || <span class="macmade-code-ctag">numberOfDelegates</span> == 0 ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span>;<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> hash = [ [ <span class="macmade-code-predefined">NSNumber</span> <span class="macmade-code-predefined">numberWithUnsignedInteger</span>: ( <span class="macmade-code-predefined">NSUInteger</span> )object ] stringValue ];<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( [ <span class="macmade-code-ctag">hashs</span> <span class="macmade-code-predefined">objectForKey</span>: hash ] == <span class="macmade-code-keyword">nil</span> ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span>;<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> index = [ [ <span class="macmade-ctag">hashs</span> <span class="macmade-code-predefined">objectForKey</span>: hash ] unsignedIntegerValue ];<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">for</span>( i = index; i &lt; <span class="macmade-code-ctag">numberOfDelegates</span> - 1; i++ ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-ctag">delegates</span>[ i ] = <span class="macmade-code-ctag">delegates</span>[ i + 1 ];<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> [ hash <span class="macmade-code-predefined">removeObjectForKey</span>: hash ];<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-ctag">numberOfDelegates</span>--;<br />
</code> <code class="macmade-source">}</code></div>
<div>Le fonctionnement de cette méthode repose sur le même principe que la précédente, avec une petite subtilité.</div>
<div>A supposer que l&#8217;on aie 5 délégués, et que l&#8217;on enlève l&#8217;objet se trouvant en position 3 dans notre tableau de pointeur, nous aurons un trou. Pour éviter cela, nous décalons donc également tous les pointeurs se trouvant après celui que nous avons ôté.</div>
<div>Et en dernier lieu, la méthode permettant d&#8217;obtenir un tableau contenant tous les objets délégués.</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-predefined">NSArray</span> * )delegates<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSUInteger</span> i;<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSMutableArray</span> * delegatesArray;<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( <span class="macmade-code-ctag">numberOfDelegates</span> == 0 ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span> [ <span class="macmade-code-predefined">NSArray</span> array ];<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> delegatesArray = [ <span class="macmade-code-predefined">NSMutableArray</span> <span class="macmade-code-predefined">arrayWithCapacity</span>: <span class="macmade-code-ctag">numberOfDelegates</span> ];<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">for</span>( i = 0; i &lt; <span class="macmade-code-ctag">numberOfDelegates</span>; i++ ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> [ delegatesArray <span class="macmade-code-predefined">addObject</span>: <span class="macmade-code-ctag">delegates</span>[ i ] ];<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span> [ <span class="macmade-code-predefined">NSArray</span> <span class="macmade-code-predefined">arrayWithArray</span>: delegatesArray ];<br />
</code> <code class="macmade-source">}<br />
</code></div>
<div>Il s&#8217;agit d&#8217;une simple boucle sur notre tableau de pointeur, qui ajoute les objets pointés dans un objet de type &#8216;NSArray&#8217;.</div>
<h3>7. Runtime et re-routage des méthodes</h3>
<div>Nous avons vu plus haut que, pour déterminer si le délégué possède une certaine méthode, il fallait utiliser la méthode &#8216;respondsToSelector&#8217; sur l&#8217;objet délégué.</div>
<div class="macmade-code"><code class="macmade-source"><span class="macmade-code-keyword">if</span>( [ <span class="macmade-code-ctag">delegate</span> <span class="macmade-code-predefined">respondsToSelector</span>: <span class="macmade-code-keyword">@selector</span>( someMethod ) ] ) {}</code></div>
<div>Pour éviter de changer les habitudes de programmation des dévelopeurs Cocoa, nous allons rendre ceci possible sur notre objet &#8216;DelegateChain&#8217;.</div>
<div>Actuellement. le code ci-dessus n&#8217;a aucune chance de fonctionner, vu que notre objet &#8216;DelegateChain&#8217;, qui contient les délégués, ne possède bien sûr pas leurs méthodes à son étage.</div>
<div>Nous pouvons par contre parfaitement surcharger (re-déclarer) dans notre classe la méthode &#8216;respondToSelector&#8217; (à l&#8217;origine, elle est déclarée dans la classe &#8216;NSObject&#8217;), pour lui affecter un comportement autre que celui par défaut.</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-keyword">BOOL</span> )<span class="macmade-code-predefined">respondsToSelector</span>: ( <span class="macmade-code-keyword">SEL</span> )selector<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSUInteger</span> i;<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">for</span>( i = 0; i &lt; <span class="macmade-code-ctag">numberOfDelegates</span>; i++ ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( [ <span class="macmade-code-ctag">delegates</span>[ i ] <span class="macmade-code-predefined">respondsToSelector</span>: selector ] == <span class="macmade-code-keyword">YES</span> ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span> <span class="macmade-code-keyword">YES</span>;<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span> <span class="macmade-code-keyword">NO</span>;<br />
</code> <code class="macmade-source">}<br />
</code></div>
<div>Nous effectuons donc une boucle sur notre tableau de pointeur, et contrôlons si l&#8217;un des délégué possède la méthode demandée. De cette manière, nous pouvons utiliser notre objet &#8216;DelegateChain&#8217; comme s&#8217;il s&#8217;agissait d&#8217;un délégué normal et unique.</div>
<div>Pour que cela fonctionne, il nous faut également surcharger la méthode &#8216;methodSignatureForSelector&#8217; (NSObject). Celle-ci permet à l&#8217;environnement runtime d&#8217;Objective-C d&#8217;obtenir les infos nécessaires sur une méthode particulière, comme son type de retour, ses arguments, etc.</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-predefined">NSMethodSignature</span> * )methodSignatureForSelector: ( <span class="macmade-code-keyword">SEL</span> )selector<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSUInteger</span> i;<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">for</span>( i = 0; i &lt; <span class="macmade-code-ctag">numberOfDelegates</span>; i++ ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( [ <span class="macmade-code-ctag">delegates</span>[ i ] <span class="macmade-code-predefined">respondsToSelector</span>: selector ] == <span class="macmade-code-keyword">YES</span> ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span> [ [ <span class="macmade-code-ctag">delegates</span>[ i ] class ] <span class="macmade-code-predefined">instanceMethodSignatureForSelector</span>: selector ];<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">return</span> <span class="macmade-code-keyword">nil</span>;<br />
</code> <code class="macmade-source">}</code></div>
<div>Désormais, nous pouvons savoir si au moins un délégué possède une méthode spécifique. Mais comment appeler le ou les délégués contenant cette méthode?</div>
<div>Ici aussi, nous allons garder le même système d&#8217;appel que pour un délégué unique, à savoir que la méthode désirée sera appelée directement sur notre objet &#8216;DelegateChain&#8217;, qui devra se charger de re-router cet appel vers le ou les délégués concernés.</div>
<div>Pour ce faire, nous allons implémenter la méthode &#8216;forwardInvocation&#8217; dans notre classe.</div>
<div>Cette dernière est automatiquement appelée par l&#8217;environnement runtime d&#8217;Objective-C lorsqu&#8217;une méthode est appelée sur un objet  ne la possédant pas. Ceci afin de donner une dernière chance à l&#8217;objet en question de gérer l&#8217;erreur.</div>
<div>Le même genre de concept est utilisé dans de nombreux langages de programmation objet. On peut par exemple citer les méthodes virtuelles de C++ ou encore la méthode &#8216;__call&#8217; en PHP5.</div>
<div class="macmade-code"><code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )forwardInvocation: ( NSInvocation * )invocation<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSUInteger</span> i;<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">for</span>( i = 0; i &lt; <span class="macmade-code-ctag">numberOfDelegates</span>; i++ ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> <span class="macmade-code-keyword">if</span>( [ <span class="macmade-code-ctag">delegates</span>[ i ] <span class="macmade-code-predefined">respondsToSelector</span>: [ invocation selector ] ] == <span class="macmade-code-keyword">YES</span> ) {<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"> [ invocation <span class="macmade-code-predefined">invokeWithTarget</span>: <span class="macmade-code-ctag">delegates</span>[ i ] ];<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source"> }<br />
</code> <code class="macmade-source">}</code></div>
<div>Le système de délégation multiple est ici complétement opérationnel. Pour en bénéficier dans une classe, il suffit désormais que cette dernière soit une sous-classe de &#8216;MultipleDelegateObject&#8217;. Aucune autre implémentation n&#8217;est nécessaire.</div>
<h3>8. Conclusion</h3>
<div>Un tel système permet de définir des classes ayant un nombre infini de délégués. Par contre, les objets intrinsèques du framework Cocoa, tels &#8216;NSWindow&#8217;, ne pourront pas bénéficier de ce système.</div>
<div>Il est par contre parfaitement envisageable d&#8217;implémenter ce système de délégation multiple sur des objets comme &#8216;NSWindow&#8217;.</div>
<div>Le language Objective-C permet en effet la définition de catégories, permettant d&#8217;ajouter des méthodes dans n&#8217;importe quel objet disponible, que celui-ci soit défini dans notre projet, ou qu&#8217;il fasse partie d&#8217;un framework du système. Par exemple:</div>
<div class="macmade-code"><code class="macmade-source"><span class="macmade-code-keyword">@interface</span> <span class="macmade-code-predefined">NSObject</span>( MyCategory )<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )sayHello;<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@end</span><br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@implementation</span> <span class="macmade-code-predefined">NSObject</span>( MyCategory )<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source">- ( <span class="macmade-code-keyword">void</span> )sayHello<br />
</code> <code class="macmade-source">{<br />
</code> <code class="macmade-source"> <span class="macmade-code-predefined">NSLog</span>( <span class="macmade-code-string">@"Hello world!"</span> );<br />
</code> <code class="macmade-source">}<br />
</code> <code class="macmade-source"><br />
</code> <code class="macmade-source"><span class="macmade-code-keyword">@end</span></code></div>
<div>Le code ci-dessus ajoute une méthode &#8216;sayHello&#8217; dans la classe &#8216;NSObject&#8217;, faisant partie du framework Cocoa. Comme &#8216;NSObject&#8217; est la classe de base pour toutes les classes Objective-C, toutes les classes disponibles possèdent maintenant une méthode &#8216;sayHello&#8217;.</div>
<div>Nous pourrions donc parfaitement ajouter les méthodes &#8216;addDelegate&#8217;, &#8216;removeDelegate&#8217; et &#8216;delegates&#8217; à l&#8217;objet &#8216;NSWindow&#8217;.</div>
<div>La seule limitation des catégories est qu&#8217;il est impossible d&#8217;ajouter des variables d&#8217;instance à une classe. Par contre, l&#8217;objet &#8216;NSWindow&#8217; possède déjà une variable d&#8217;instance prévue pour le délégué. Il faudra simplement ne pas oublier de redéfinir la méthode &#8216;setDelegate&#8217; de &#8216;NSWindow&#8217; dans notre catégorie. L&#8217;utilisation d&#8217;une variable globale statique (donc dont l&#8217;accès est limité au fichier qui l&#8217;a déclarée) est également une possibilité envisageable pour stocker les chaînes de délégués.</div>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2009/08/24/implementation-d-un-systeme-de-delegation-multiple-en-objective-c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>HOWTO : Get the best out of twitter</title>
		<link>http://blog.netinfluence.com/2009/06/15/howto-get-the-best-out-of-twitter/</link>
		<comments>http://blog.netinfluence.com/2009/06/15/howto-get-the-best-out-of-twitter/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 21:01:00 +0000</pubDate>
		<dc:creator>sandrine</dc:creator>
				<category><![CDATA[reach]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[socialmedia]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=11</guid>
		<description><![CDATA[You will find lots of best practices and advices to handle your twitter account. I think the basis you should set up, to start with is the following. Encourage your visitors to publicize your content ShareThis is a small plugin to add to your site / blog allowing each of your visitors, who liked the post, to publish it in their favorite social network; like facebook profile, twitter, delicious&#8230; The easier you make it for people to share what they like, the more they tend to do this little additional click to share. I use this one but their are other tools including, for those using wordpres, native plugins. I found this one smart and easy to configure. Since we [...]]]></description>
			<content:encoded><![CDATA[<p>You will find lots of best practices and advices to handle your twitter account. I think the basis you should set up, to start with is the following.</p>
<p><strong>Encourage your visitors to publicize your content</strong><br />
<a href="http://sharethis.com/">ShareThis</a> is a small plugin to add to your site / blog allowing each of your visitors, who liked the post, to publish it in their favorite social network; like facebook profile, twitter, delicious&#8230;  <img style="float: right; margin: 0 0 1em 1em;" title="sharethis-detail.png, juin 2009" src="/public/Sandrine/sharethis-detail.png" alt="sharethis-detail.png" />The easier you make it for people to share what they like, the more they tend to do this little additional click to share.  I use this one but their are other tools including, for those using wordpres, native plugins.  I found this one smart and easy to configure.  Since we added this plugin (last week), we already got 10 sharings. <strong><em>Make life simpler is key for your visitors comfort.</em></strong></p>
<p><strong>Automatically publish a link to your content</strong><br />
<a href="https://twitterfeed.com/"><img style="float: left; margin: 0 1em 1em 0;" title="twitterfeed.png, juin 2009" src="/public/Sandrine/twitterfeed.png" alt="twitterfeed.png" /></a><a href="https://twitterfeed.com/">Twitterfeed</a> is a smart tool which crawls your blog feed for updates and publishes it according to your preferences on your twitter account.  Easy to use, it allows you to automatically get visibility for your content on twitter, without having to think about it.  You can also add a prefix to your post so that people see it comes from your blog : see following screenshot.<br />
<strong><em>You create content, sharing it is important for your followers.</em></strong></p>
<p><img title="twitterfeed-detail.png, juin 2009" src="/public/Sandrine/.twitterfeed-detail_m.jpg" alt="twitterfeed-detail.png" /></p>
<p><strong>Show you have a twitter account they can follow</strong><br />
<a href="http://twitter.com"><img style="float: left; margin: 0 1em 1em 0;" title="followus.png, juin 2009" src="/public/Sandrine/followus.png" alt="followus.png" /></a>By adding a logo mentioning your twitter account, you will encourage those using it and liking it to add themselves to your followers.  You will gain instant followers just by mentioning your presence.  Opt in based, twitter allows people to follow those they like.  But many of us have various accounts and read many sources and don&#8217;t necessary have time to spend to look for if the blog / company has a twitter.<br />
Of course, if you have a linkedin, facebook profile or a corporate website, make a mention of this twitter address too! <strong><em>Make it fast for people to see you have a twitter account.</em></strong></p>
<p><strong>Follow your conversations, replies, comments</strong><br />
Twitter main interest is to generate conversations.  Tracking it is therefore essential. For this item you can use several solutions :</p>
<ol>
<li>Configure the notifications within <a href="http://twitter.com/">your twitter account</a> &gt; This solution can become quite invasive.  If you receive many followers and replies, it can happen you end up spammed by notifications, and miss out replies.  RT (retweets) are not sent via this notification system which may also make you forget some important RT for you.</li>
<li><a href="http://www.twhirl.org"><img style="float: right; margin: 0 0 1em 1em;" title="twhirl.png, juin 2009" src="/public/Sandrine/twhirl.png" alt="twhirl.png" /></a>Use an air application for your desktop tp follow your conversations.  My preference goes out to <a href="http://www.twhirl.org/">twhirl</a>. This application handles multi account (you can open as many windows as you get accounts, alerts you for replies (sound) and gives you a quick access to RT, DM, @s (retweets, direct messages and replies).</li>
<li><a href="https://cotweet.com/"><img style="float: right; margin: 0 0 1em 1em;" title="cotweet.png, juin 2009" src="/public/Sandrine/cotweet.png" alt="cotweet.png" /></a>Last but not least, you may use <a href="https://cotweet.com/">Co-tweet</a>.  This applications, still under beta, allows you to track all this conversation flow for you not to forget any.  I am just testing it and haven&#8217;t found yet how to configure alerts and set a local app, but it is nice and easy to use.</li>
</ol>
<p><strong>&#8220;Make sure you do not miss replies, messages or retweets to take advantage of conversations.&#8221;</strong></p>
<p><strong>Add / find interesting people to follow</strong> <a href="http://wefollow.com"><img style="float: left; margin: 0 1em 1em 0;" title="wefollow.png, juin 2009" src="/public/Sandrine/wefollow.png" alt="wefollow.png" /></a>You will find many directories which will be more or less useful and more or less usable.  My favourite is the <a href="http://wefollow.com/">wefollow</a> directory.  Simple, based on tages it allows you to add your twitter according to your 3 best tags and also find similar twitter.  Very useful for instance to follow tweets in the tech, social media or in regions. The other one I tries is <a href="http://www.twellow.com/">twellow</a>.  More or less working like the yellow pages it allows you to find twitter accounts you might be interested in.</p>
<p><strong>Analyze / follow your stats</strong> Here I found two useful tools :</p>
<ol>
<li><a href="http://twitterholic.com/">Twitterholic</a> crawls your site to provide you with daily / main changes stats and follow your progression trend.  It provides with an historic view of how / when your account gained followers and friends.</li>
<li><a href="http://tweeteffect.com/">Tweeteffect</a> is probably the best tip of this list.  It will not draw any attention nor publicize anything for you, but will help you understanding how your tweets work.  By indicating the number of followers you gained after each of your twitter posts, you will be able to understand what works and what doesn&#8217;t work for your users (what they like).. When planning a &#8220;marketing&#8221; and active content / value driven twitter account, this can be quite important and useful for you to understand what works for you.</li>
</ol>
<p>There are plenty of tools around you may add to this list but I reckon you should concentrate and take advantage of this quick and not really demanding optimization. I hope you enjoyed this post and feel free to add your favorites to this list too, and of course, <a href="http://twitter.com/netinfluence">follow us on twitter</a> <img src='http://blog.netinfluence.com/wp-content/plugins/smilies-themer/Silk/emoticon_wink.png' alt=';-)' class='wp-smiley' /> </p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2009/06/15/howto-get-the-best-out-of-twitter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

