<?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; Développement</title>
	<atom:link href="http://blog.netinfluence.com/tag/developpement/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>Gordon Brown et Tim Berners-Lee: concilier web et développement</title>
		<link>http://blog.netinfluence.com/2011/04/08/gordon-brown-et-tim-berners-lee-concilier-web-et-developpement/</link>
		<comments>http://blog.netinfluence.com/2011/04/08/gordon-brown-et-tim-berners-lee-concilier-web-et-developpement/#comments</comments>
		<pubDate>Fri, 08 Apr 2011 12:58:01 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[think]]></category>
		<category><![CDATA[Berners-Lee]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[Gordon brown]]></category>
		<category><![CDATA[Unige]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.com/?p=4475</guid>
		<description><![CDATA[netinfluence a assisté à la conférence exceptionnelle de Tim Berners-Lee, inventeur du World Wide Web, et Gordon Brown, ancien premier ministre britannique, qui s’est tenue à l’université de Genève le 6 avril. Sous un format de discussion ouverte, modéré par Alberto Ibargüen, directeur de la Fondation Knight, les deux hommes ont abordés des thèmes liés aux possibilités offertes par le web &#8220;ouvert&#8221; pour favoriser le développement et la démocratisation. Que retenons nous de cette conférence? Dans certaines régions du monde, notamment les pays en voie de développement, la majorité de la population n’a pas encore accès au web. Ce n’est pas tellement le manque d’infrastructures et de connexions à Internet qui est en cause (en effet le taux de pénétration [...]]]></description>
			<content:encoded><![CDATA[<p>netinfluence a assisté à la conférence exceptionnelle de <strong>Tim Berners-Lee</strong>, inventeur du World Wide Web, et <strong>Gordon Brown</strong>, ancien premier ministre britannique, qui s’est tenue à l’université de Genève le 6 avril.</p>
<p>Sous un format de discussion ouverte, modéré par Alberto Ibargüen, directeur de la Fondation Knight, les deux hommes ont abordés des thèmes liés aux possibilités offertes par le web &#8220;ouvert&#8221; pour favoriser le développement et la démocratisation.</p>
<p><strong>Que retenons nous de cette conférence? </strong></p>
<p>Dans certaines régions du monde, notamment les pays en voie de développement, la majorité de la population n’a pas encore accès au web.</p>
<p>Ce n’est pas tellement le manque d’infrastructures et de connexions à Internet qui est en cause (en effet le taux de pénétration des technologies mobiles se situe aux alentrous de 40% en Afrique), <strong>mais le manque de représentativité des langues locales sur la toile et l&#8217;illettrisme</strong> qui touche plus d’un milliard d’adultes dans le monde.</p>
<p>Le net ne peut-il quand même aider les populations défavorisées? Pour Gordon Brown, <strong>Internet reste l&#8217;un des meilleurs moyen de développement</strong>: il amène du savoir, il ouvre des opportunités incroyables et de ce fait dynamise l&#8217;économie d&#8217;un pays et crée des emplois.</p>
<p>Pour illustrer son point de vue, l&#8217;ancien premier ministre britannique, a donné l’exemple d’un <a href="http://www.youtube.com/watch?v=a0tmJL_GIhQ ">village</a> dont les habitants, producteurs de tomates, avaient du mal à fixer le prix des denrées, maîtriser la distribution et les marges. Grâce à l&#8217;arrivée d&#8217;Internet à la bibliothèque du village, ils ont pu accéder à des informations cruciales et résoudre leurs problèmes.</p>
<p>Similairement, une personne de l’auditoire a donné l&#8217;exemple étonnant d&#8217;un village indien, ou une <a href="http://www.itcportal.com/ruraldevp_philosophy/echoupal.htm">borne Internet a été placée</a>. Au bout de 6 mois, les enfants du village savaient maîtriser l&#8217;ordinateur et lire les textes en anglais.</p>
<p>Tim Berners-Lee y voit l’importance de faire confiance aux gens en leur offrant une connexion à Internet. Son adoption est probablement plus facile que prévu et le problème de la langue, même si important, n’est pas un problème insurmontable: <strong>il faut faire d’Internet un média multi-langues et ne pas se limiter à l’anglais</strong>.</p>
<p>Les deux membres de la World Wide Web Foundation, un organisme qui lutte pour maintenir la liberté d’accès au Web, ont donc clairement argumenté dans ce sens. Mais ils n&#8217;ont pas forcément partagé une vision ou des propositions concrètes sur les réflexions des gouvernements, organisations internationales ou même entreprises.</p>
<p>Rien n’a été dit non plus sur les bouleversements en profondeur du web, sur sa commercialisation ou sa transformation en <a href="http://www.telegraph.co.uk/technology/facebook/8151101/tTim-Berners-Lee-criticises-Facebooks-walled-garden.html">«prison dorée»</a>.</p>
<p>Retrouvez la vidéo de la conférence <a href="http://www.unige.ch/presse/archives/2011/web-tblgb.html">ici</a>.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2011/04/08/gordon-brown-et-tim-berners-lee-concilier-web-et-developpement/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lancement d’alcooquizz</title>
		<link>http://blog.netinfluence.com/2010/07/15/lancement-dalcooquizz/</link>
		<comments>http://blog.netinfluence.com/2010/07/15/lancement-dalcooquizz/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 07:11:24 +0000</pubDate>
		<dc:creator>sandrine</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[CHUV]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[netinfluence]]></category>
		<category><![CDATA[typo3]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=2055</guid>
		<description><![CDATA[Nous avons été mandaté par le CHUV et son département d&#8217;alcoologie pour réaliser un site de prévention et d&#8217;information sur les risques liés à l&#8217;alcool nommé alcooquizz.ch.  Le site fonctionne comme un questionnaire qui permet à chaque personne d&#8217;évaluer sa situation par rapport à l&#8217;alcool.  Le diagnostique, à la fois personnalisé et anonyme, fournit des informations précises ainsi que des recommandations adaptées précisément à la situation de chacun. Annoncé aujourd&#8217;hui par une conférence de presse, le site va faire l&#8217;objet d&#8217;une plus vaste campagne de communication, relayée notamment durant les divers festivals de l&#8217;été afin de sensibiliser sans stigmatiser ni culpabiliser. La particularité de ce projet a été pour nous de bâtir tout un concept qui permette une certaine neutralité. [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_2062" class="wp-caption alignright" style="width: 310px"><a rel="attachment wp-att-2062" href="http://blog.netinfluence.com/2010/07/15/lancement-dalcooquizz/"><img class="size-medium wp-image-2062  " title="Alcooquizz - le site du CHUV  pour l'alcoologie" src="http://blog.netinfluence.ch/wp-content/uploads/2010/07/Capture-d’écran-2010-07-15-à-08.44.44-300x196.png" alt="Site réalisé par netinfluence" width="300" height="196" /></a><p class="wp-caption-text">Homepage d&#39;alcooquizz</p></div>
<p>Nous avons été mandaté par le CHUV et son département d&#8217;alcoologie pour réaliser un site de prévention et d&#8217;information sur les risques liés à l&#8217;alcool nommé <a title="voir le site : alcooquizz" href="http://www.alcooquizz.ch/" target="_blank">alcooquizz.ch</a>.  Le site fonctionne comme un questionnaire qui permet à chaque personne d&#8217;évaluer sa situation par rapport à l&#8217;alcool.  Le diagnostique, à la fois personnalisé et anonyme, fournit des informations précises ainsi que des recommandations adaptées précisément à la situation de chacun.</p>
<p>Annoncé aujourd&#8217;hui par une conférence de presse, le site va faire l&#8217;objet d&#8217;une plus vaste campagne de communication, relayée notamment durant les divers festivals de l&#8217;été afin de sensibiliser sans stigmatiser ni culpabiliser.</p>
<p>La particularité de ce projet a été pour nous de bâtir tout un concept qui permette une certaine neutralité. Il fallait pouvoir parler d&#8217;alcool sans culpabiliser, être agréable avec un style un peu ludique mais pas trop non plus et sensibiliser et informer sans non plus provoquer de malaise.  Bref, créer une prise de conscience et permettre peut être de nouveaux réflexes par rapport à l&#8217;alcool car on se rend compte que beaucoup d&#8217;idées reçues existent sur le sujet mais que finalement les gens savent très peu.</p>
<div id="attachment_2063" class="wp-caption alignright" style="width: 310px"><a href="http://www.alcooquizz.ch/fr/alcoopedia/"><img class="size-medium wp-image-2063 " title="Alcoopedia - Base de  connaissance du site" src="http://blog.netinfluence.ch/wp-content/uploads/2010/07/Capture-d’écran-2010-07-15-à-09.16.33-300x198.png" alt="" width="300" height="198" /></a><p class="wp-caption-text">Alcoopedia - Base de connaissance du site</p></div>
<p>La base de connaissance, alcoopedia, s&#8217;enrichira au fur et à mesure des interactions et des questions avec le site.  Bâtie avec un nuage de tags, elle permet de remonter les articles les plus demandés ainsi que les mots les plus recherchés.</p>
<p>Nous avons conçu le branding (alcooquizz et alcoopedia) ainsi que toute l&#8217;identité visuelle du logo et du site.  Nous avons également développé le site web (en flex &amp; typo3) qui sera prochainement décliné sous forme d&#8217;une application iPhone.  Le CHUV et son équipe ont quant à eux fait un énorme travail de préparation et de rédaction pour que le site s&#8217;inscrive aussi dans la lignée des travaux de l&#8217;OMS et serve à terme, de base statistique sur les comportements liés à l&#8217;alcool.</p>
<p>Nous sommes ravis d&#8217;avoir contribué à ce beau projet et préparons actuellement la suite.</p>
<p>C&#8217;est une manière inédite de communiquer sur un sujet aussi sensible et nous sommes curieux de voir comment le projet sera reçu par les citoyens et les médias.<br />
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="270" 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://www.dailymotion.com/swf/video/xe1uss" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="480" height="270" src="http://www.dailymotion.com/swf/video/xe1uss" allowscriptaccess="always" allowfullscreen="true"></embed></object><br />
Update :</p>
<p>Les premières retombées sont plutôt positives avec pour la première journée d&#8217;introduction du site avec 6&#8217;700 visiteurs et déjà quelques articles.</p>
<p><a title="20minutes" href="http://www.20min.ch/ro/news/vaud/story/Evaluez-votre-consommation-d-alcool-19430396" target="_blank">http://www.20min.ch/ro/news/vaud/story/Evaluez-votre-consommation-d-alcool-19430396</a></p>
<p><a title="TDG" href="http://www.tdg.ch/evaluez-consommation-alcool-site-web-2010-07-15" target="_blank">http://www.tdg.ch/evaluez-consommation-alcool-site-web-2010-07-15</a></p>
<p><a title="lematin" href="http://www.lematin.ch/actu/suisse/evaluez-consommation-alcool-site-web-299738" target="_blank">http://www.lematin.ch/actu/suisse/evaluez-consommation-alcool-site-web-299738</a></p>
<p><a title="24heures" href="http://www.24heures.ch/evaluez-consommation-alcool-site-web-2010-07-15" target="_blank">http://www.24heures.ch/evaluez-consommation-alcool-site-web-2010-07-15</a></p>
<p><a title="TSR" href="http://www.tsr.ch/info/suisse/2275848-un-site-web-pour-evaluer-son-rapport-a-l-alcool.html" target="_blank">http://www.tsr.ch/info/suisse/2275848-un-site-web-pour-evaluer-son-rapport-a-l-alcool.html</a></p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2010/07/15/lancement-dalcooquizz/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Ar-PHP : boite à outils pour gérer les spécificités de la langue arabe</title>
		<link>http://blog.netinfluence.com/2010/07/12/ar-php-boite-a-outils-pour-gerer-les-specificites-de-la-langue-arabe/</link>
		<comments>http://blog.netinfluence.com/2010/07/12/ar-php-boite-a-outils-pour-gerer-les-specificites-de-la-langue-arabe/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 08:52:01 +0000</pubDate>
		<dc:creator>netinfluence</dc:creator>
				<category><![CDATA[create]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=2001</guid>
		<description><![CDATA[Ar-PHP est une librairie PHP qui apporte un certain nombre d&#8217;outils pratiques pour les utilisateurs arabophones. De part sa spécificité, la langue arabe n&#8217;est pas toujours très bien gérée dans les logiciels actuels. Lorsqu&#8217;on désire mettre en place un site web en arabe, et plus particulièrement destiné au monde arabe, il est nécessaire de disposer d&#8217;un certains nombres d&#8217;outils afin de rendre le site le plus agréable possible pour les utilisateurs. Voici une liste non exhaustive des principales fonctionnalités offertes par Ar-PHP : Conversion de dates entre le calendrier grégorien et hégirien ; Conversion de dates hégiriennes en timestamp Unix ; Translitération de mots anglais en arabe et vice versa ; Détection et application d&#8217;un character set ; Détection de [...]]]></description>
			<content:encoded><![CDATA[<p>Ar-PHP est une librairie PHP qui apporte un certain nombre d&#8217;outils pratiques pour les utilisateurs arabophones. De part sa spécificité, la langue arabe n&#8217;est pas toujours très bien gérée dans les logiciels actuels. Lorsqu&#8217;on désire mettre en place un site web en arabe, et plus particulièrement destiné au monde arabe, il est nécessaire de disposer d&#8217;un certains nombres d&#8217;outils afin de rendre le site le plus agréable possible pour les utilisateurs. Voici une liste non exhaustive des principales fonctionnalités offertes par Ar-PHP :</p>
<ul>
<li>Conversion de dates entre le calendrier grégorien et <a href="http://fr.wikipedia.org/wiki/Calendrier_musulman" target="_blank">hégirien</a> ;</li>
<li>Conversion de dates hégiriennes en timestamp Unix ;</li>
<li>Translitération de mots anglais en arabe et vice versa ;</li>
<li>Détection et application d&#8217;un character set ;</li>
<li>Détection de texte en arabe dans un document multilingue ;</li>
<li>Calcul des horaires de prière en fonction des coordonnées GPS ;</li>
<li>Clavier arabe virtuel en javascript ;</li>
<li>Normalisation du texte arabe.</li>
</ul>
<p>Certaines des fonctionnalités offertes par cette librairie s&#8217;avèrent rapidement indispensables si on souhaite gérer au mieux les spécificités de la langue arabe.</p>
<p>Ce projet est développé par Khaled Al-Sham&#8217;aa en opensource. L&#8217;installation se fait soit par PEAR, soit en téléchargeant directement le code source. Pour découvrir plus en détail cette librairie, rendez-vous sur le site web du projet : <a href="http://www.ar-php.org/en_index-php-arabic.html">http://www.ar-php.org</a></p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2010/07/12/ar-php-boite-a-outils-pour-gerer-les-specificites-de-la-langue-arabe/feed/</wfw:commentRss>
		<slash:comments>0</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>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>Le marché des applications iPhone en Suisse c’est de la dynamique!</title>
		<link>http://blog.netinfluence.com/2010/02/18/le-marche-des-applications-iphone-en-suisse-cest-de-la-dynamique/</link>
		<comments>http://blog.netinfluence.com/2010/02/18/le-marche-des-applications-iphone-en-suisse-cest-de-la-dynamique/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 20:01:27 +0000</pubDate>
		<dc:creator>sandrine</dc:creator>
				<category><![CDATA[create]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[application iphone]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[itunes]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=937</guid>
		<description><![CDATA[Plus une marque ne peut se passer de son application mobile.  Résultat des courses, la demande pour la création d&#8217;applications iPhone a explosé en 2009. C&#8217;est d&#8217;ailleurs pour en parler que Bilan a réuni les développeurs romands pour un article intitulé : les suisses les rois des applications. Principalement composé de développeurs indépendants, le marché suisse n&#8217;est pas en reste dans la production d&#8217;applications iPhone.  Ayant organisé la premières iPhone  conférence en 2008, Bilan nous a interrogé sur ce qui avait évolué en 2009. De notre point de vue les demandes ont évolué en nombre mais surtout en qualité. Plus habitués et mieux informés, les demandeurs ont compris le besoin de faire une application &#8220;qui sert&#8221; ou &#8220;attire l&#8217;attention&#8221; sous [...]]]></description>
			<content:encoded><![CDATA[<p>Plus une marque ne peut se passer de son application mobile.  Résultat des courses, la demande pour la création d&#8217;applications iPhone a explosé en 2009. C&#8217;est d&#8217;ailleurs pour en parler que Bilan a réuni les développeurs romands pour un article intitulé : <a title="Article de Bilan" href="http://www.bilan.ch/dossier/les-suisses-rois-des-applications">les suisses les rois des applications</a>.</p>
<p>Principalement composé de développeurs indépendants, le marché suisse n&#8217;est pas en reste dans la production d&#8217;applications iPhone.  Ayant organisé la premières iPhone  conférence en 2008, Bilan nous a interrogé sur ce qui avait évolué en 2009.</p>
<p>De notre point de vue les demandes ont évolué en nombre mais surtout en qualité.<br />
Plus habitués et mieux informés, les demandeurs ont compris le besoin de faire une application &#8220;qui sert&#8221; ou &#8220;attire l&#8217;attention&#8221; sous peine de tomber dans l&#8217;abime d&#8217;itunes.  Donc fini les briefs un peu folkloriques et les &#8220;me too&#8221;.<br />
Les demandes sont également beaucoup plus raisonnables en terme de budget.  On ne développe pas une application iPhone en deux jours!  Les coûts sont ceux d&#8217;un site web, voire largement plus dès que l&#8217;on rentre dans des applications complexes comme le jeu.<br />
Enfin, la maturité du marché a soulevé un véritable enthousiasme créatif.  Les demandes que nous recevons ces derniers temps sont vraiment plus réfléchies et créatives.  On ressent une vrai réflexion stratégique donnant une vrai place aux applications mobile dans la stratégie de présence online des entreprises.</p>
<p>Il reste encore beaucoup à découvrir et je me réjoui notamment de développer notre première application iPad <img src='http://blog.netinfluence.com/wp-content/plugins/smilies-themer/Silk/emoticon_wink.png' alt=';-)' class='wp-smiley' /> </p>
<p>Si vous souhaitez en savoir plus ou rejoindre ce microcosme, je vous encourage à aller voir les initiatives suivantes.<br />
De nombreux groupes se sont créés comme &#8220;<a title="Linkedin group" href="http://www.linkedin.com/groups?gid=696197&amp;trk=myg_ugrp_ovr" target="_blank">iphone group for developers &amp; decision makers</a>&#8221; ou &#8220;<a title="Groupe facebook" href="http://www.facebook.com/group.php?gid=39755092833" target="_blank">les développeurs de Suisse romande</a>&#8221; sans oublier les &#8220;<a title="mobile mondays" href="http://www.mobilemonday.ch/" target="_blank">mobile mondays</a>&#8220;.</p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2010/02/18/le-marche-des-applications-iphone-en-suisse-cest-de-la-dynamique/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>TYPO3 et Campaign Monitor</title>
		<link>http://blog.netinfluence.com/2010/01/04/typo3-et-campaign-monitor/</link>
		<comments>http://blog.netinfluence.com/2010/01/04/typo3-et-campaign-monitor/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 15:01:23 +0000</pubDate>
		<dc:creator>macmade</dc:creator>
				<category><![CDATA[create]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[newsletter]]></category>
		<category><![CDATA[Online PR & communication]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[typo3]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=522</guid>
		<description><![CDATA[Pour les utilisateurs du CMS TYPO3 et du service Campaign Monitor, netinfluence vient de publier une extension TYPO3 permettant l'enregistrement d'une adresse email dans une liste gérée par Campaign Monitor depuis le frontend TYPO3.]]></description>
			<content:encoded><![CDATA[<div>Pour les utilisateurs du CMS <a href="http://typo3.org/">TYPO3</a> et du service <a href="http://www.campaignmonitor.com/">Campaign Monitor</a>, netinfluence vient de publier une extension TYPO3 permettant l&#8217;enregistrement d&#8217;une adresse email dans une liste gérée par Campaign Monitor depuis le frontend TYPO3.</p>
<p>Cette extension peut-être <a href="http://typo3.org/extensions/repository/view/netmailing/current/">téléchargée</a> depuis le site officiel de TYPO3.</p>
<p>La <a href="http://typo3.org/documentation/document-library/extension-manuals/netmailing/1.0.0/view/">documentation</a> est également disponible directement en ligne.</p>
</div>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2010/01/04/typo3-et-campaign-monitor/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>Comprendre les nombres à virgule flottante</title>
		<link>http://blog.netinfluence.com/2009/09/24/comprendre-les-nombres-a-virgule-flottante/</link>
		<comments>http://blog.netinfluence.com/2009/09/24/comprendre-les-nombres-a-virgule-flottante/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 08:55:00 +0000</pubDate>
		<dc:creator>macmade</dc:creator>
				<category><![CDATA[create]]></category>
		<category><![CDATA[Développement]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=53</guid>
		<description><![CDATA[<p>Les nombres à virgule flottante à précision simple sont le plus souvent appelés 'float' ou 'real'. Cet article explique comment ces nombres sont gérés par un ordinateur, au niveau binaire.</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 href="http://www.gnu.org/copyleft/fdl.html" title="Free Documentation License">http://www.gnu.org/copyleft/fdl.html</a> </div>
</p></div>
<h2>Représentation binaire des nombres à virgule flottante à précision simple</h2>
<div> Les nombres à virgule flottante à précision simple sont le plus souvent appelés &#8216;float&#8217; ou &#8216;real&#8217;. Ils sont longs de 4 bytes, et sont formés de la manière suivante, de gauche à droite: </div>
<div>
<ul>
<li>Signe:    1 bit</li>
<li>Exposant: 8 bits</li>
<li>Mantisse: 23 bits</li>
</ul></div>
<div>
<table class="macmade">
<tbody>
<tr>
<td>X</td>
<td>XXXX XXXX</td>
<td>XXX XXXX XXXX XXXX XXXX XXXXX</td>
</tr>
<tr>
<th>Signe<br />1 bit</th>
<th>Exposant<br />8 bits</th>
<th>Mantisse<br />23 bits</th>
</tr>
</tbody>
</table></div>
<div> Le signe indique si le nombre est positif ou négatif (zéro pour les nombres positifs et un pour les négatifs). </div>
<div> L&#8217;exposant réel est calculé en soustrayant 127 à la valeur du champ exposant. Il s&#8217;agit de l&#8217;exposant du nombre, tel qu&#8217;exprimé en notation scientifique. </div>
<div> La mantisse complète, parfois aussi appelée significande, doit être considérée comme une valeur sur 24 bits. En effet, comme nous utilisons la notation scientifique, il y a un premier bit implicite (appelé parfois le bit caché) dont la valeur est fixée à 1, étant donné qu&#8217;il n&#8217;y a jamais de 0 en tout premier, en notation scientifique.<br />
 Par exemple, on ne dira jamais <code class="macmade">0.123 · 10<span class="macmade-power">5</span></code> mais bien <code class="macmade">1.23 · 10<span class="macmade-power">4</span></code>. </div>
<div> La conversion est effectuée de la manière suivante: </div>
<div class="macmade-code"> <code class="macmade">-1<span class="macmade-power">S</span> · 1.M · 2<span class="macmade-power">( E - 127 )</span></code> </div>
<div> Où S est le signe, M la mantisse, et E l&#8217;exposant. </div>
<h3>2. Exemple</h3>
<div> Prenons par exemple <code class="macmade">0100 0000 1011 1000 0000 0000 0000 0000</code>, ou <code class="macmade">0x40B80000</code> en notation hexadécimale. </div>
<div>
<table class="macmade">
<tbody>
<tr>
<th>Hexadécimal</th>
<td>4</td>
<td class="macmade-alt">0</td>
<td>B</td>
<td class="macmade-alt">8</td>
<td>0</td>
<td class="macmade-alt">0</td>
<td>0</td>
<td class="macmade-alt">0</td>
</tr>
<tr>
<th>Binaire</th>
<td>0100</td>
<td class="macmade-alt">0000</td>
<td>1011</td>
<td class="macmade-alt">1000</td>
<td>0000</td>
<td class="macmade-alt">0000</td>
<td>0000</td>
<td class="macmade-alt">0000</td>
</tr>
</tbody>
</table></div>
<div>
<table class="macmade">
<tbody>
<tr>
<th>Signe</th>
<th>Exposant</th>
<th>Mantisse</th>
</tr>
<tr>
<td>0</td>
<td>1000 0001</td>
<td>(1) 011 1000 0000 0000 0000 0000</td>
</tr>
</tbody>
</table></div>
<div>
<ul>
<li>Le signe est <code class="macmade">0</code>, le nombre est donc positif.</li>
<li>Le champ exposant est <code class="macmade">1000 0001</code>, autrement dit 129 en décimal. La valeur réelle de l&#8217;exposant est donc 129 &#8211; 127, ce qui nous donne 2.</li>
<li>La mantisse, avec le premier bit implicite, est <code class="macmade">1011 1000 0000 0000 0000 0000</code>.</li>
</ul></div>
<div> La représentation finale du nombre en notation scientifique binaire est donc: </div>
<div class="macmade-code"> <code class="macmade">-1<span class="macmade-power">0</span> · 1.0111 · 2<span class="macmade-power">2</span></code> </div>
<div> Mathématiquement, cela veut dire: </div>
<div class="macmade-code"> <code class="macmade">1 · ( 1 · 2<span class="macmade-power">0</span> + 0 · 2<span class="macmade-power">-1</span> + 1 · 2<span class="macmade-power">-2</span> + 1 · 2<span class="macmade-power">-3</span> + 1 · 2<span class="macmade-power">-4</span> ) · 2<span class="macmade-power">2</span></code><br />
 <code class="macmade">( 2<span class="macmade-power">0</span> + 2<span class="macmade-power">-2</span> + 2<span class="macmade-power">-3</span> + 2<span class="macmade-power">-4</span> ) · 2<span class="macmade-power">2</span></code><br />
 <code class="macmade">2<span class="macmade-power">2</span> + 2<span class="macmade-power">0</span> + 2<span class="macmade-power">-1</span> + 2<span class="macmade-power">-2</span></code><br />
 <code class="macmade">4 + 1 + 0.5 + 0.25</code> </div>
<div> La valeur du nombre à virgule flottante est donc 5.75. </div>
<h3>3. Nombres spéciaux</h3>
<div> En fonction de la valeur du champ exposant, certain nombres peuvent avoir une valeur spéciale. Ils peuvent être: </div>
<div>
<ul>
<li>Des nombres dénormalisés</li>
<li>Zéro</li>
<li>Infini</li>
<li>NaN (not a number, pas un nombre)</li>
</ul></div>
<h4>3.1. Nombres dénormalisés</h4>
<div> Si la valeur du champ exposant est 0, et que la valeur de la mantisse est plus grande que 0, le nombre doit alors être traité comme un nombre dénormalisé.<br />
 Dans un tel cas, l&#8217;exposant n&#8217;est pas -127, mais -126. Le premier bit implicite, quand à lui, n&#8217;est pas 1 mais 0.<br />
 Cela permet la représentation de nombres plus petits. </div>
<div> La notation scientifique d&#8217;un nombre dénormalisé est: </div>
<div class="macmade-code"> <code class="macmade">-1<span class="macmade-power">S</span> ·  0.M · 2<span class="macmade-power">-126</span></code> </div>
<h4>3.2. Zéro</h4>
<div> Si le champ exposant et la mantisse ont tous deux pour valeur 0, le nombre final est 0. Le bit du signe est autorisé, permettant un zéro positif ou négatif, même si cela n&#8217;a pas un grand sens mathématiquement.<br />
 Il est à noter que zéro peut être considéré comme un nombre dénormalisé. Dans ce cas, cela veut dire <code class="macmade">0 · 2<span class="macmade-power">-126</span></code>, ce que nous donne bien zéro. </div>
<h4>3.3. Infini</h4>
<div> Si la valeur du champ exposant est 255 (les 8 bits définis à 1) et si la valeur de la mantisse est 0, le nombre correspont à l&#8217;infinité, soit posistive ou négative, en fonction du signe. </div>
<h4>3.4. NaN</h4>
<div> Si la valeur du champ exposant est 255 (les 8 bits définis à 1) et si la valeur de la mantisse n&#8217;est pas 0, la valeur ne doit pas être considérée comme un nombre. Dans un tel cas, le signe n&#8217;a aucune signification. </div>
<h3>3. Portée</h3>
<div> La portée est différente pour les nombres normalisés et dénormalisés. La portée pour ces deux cas est indiquée ci-dessous: </div>
<h4>3.1 Nombres normalisés</h4>
<div>
<ul>
<li><strong>Minimum:</strong> <code class="macmade">±1.1754944909521E-38</code> / <code class="macmade">±1.00000000000000000000001<span class="macmade-power">-126</span></code></li>
<li><strong>Maximum:</strong> <code class="macmade">±3.4028234663853E+38</code> / <code class="macmade">±1.11111111111111111111111<span class="macmade-power">128</span></code></li>
</ul></div>
<h4>3.2 Nombres dénormalisés</h4>
<div>
<ul>
<li><strong>Minimum:</strong> <code class="macmade">±1.4012984643248E-45</code> / <code class="macmade">±0.00000000000000000000001<span class="macmade-power">-126</span></code></li>
<li><strong>Maximum:</strong> <code class="macmade">±1.1754942106924E-38</code> / <code class="macmade">±0.11111111111111111111111<span class="macmade-power">-126</span></code></li>
</ul></div>
<h3>4. Exemple de code C</h3>
<div> Voici un exemple de programme C qui converti un nombre binaire en sa représentation en nombre à virgule flottante: </div>
<div class="macmade-code"> <code class="macmade-source"><span class="macmade-code-comment">/* System includes */</span></code><br />
 <code class="macmade-source"><span class="macmade-code-keyword">#include</span> &lt;stdlib.h&gt;</code><br />
 <code class="macmade-source"><span class="macmade-code-keyword">#include</span> &lt;stdio.h&gt;</code><br />
 <code class="macmade-source"><span class="macmade-code-keyword">#include</span> &lt;math.h&gt;</code></p>
<p> <code class="macmade-source"><span class="macmade-code-comment">/* Definition of the boolean data type */</span></code><br />
 <code class="macmade-source"><span class="macmade-code-keyword">typedef</span> <span class="macmade-code-keyword">enum</span> { <span class="macmade-code-keyword">FALSE</span>, <span class="macmade-code-keyword">TRUE</span> } boolean;</code></p>
<p> <code class="macmade-source"><span class="macmade-code-comment">/**</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * Converts a integer to its float representation</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * </span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * This function converts a 32 bits integer to a single precision floating point</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * number, as specified by the IEEE Standard for Floating-Point Arithmetic</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * (IEEE 754). This standard can be found at the folowing address:</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * {@link http://ieeexplore.ieee.org/servlet/opac?punumber=4610933}</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * </span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * @param   unsigned long   The integer to convert to a floating point value</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * @return  float           The floating point number</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * @author                  Jean-David Gadina &lt;macmade@netinfluence.com&gt;</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> */</span></code><br />
 <code class="macmade-source"><span class="macmade-code-keyword">float</span> binaryToFloat( <span class="macmade-code-keyword">unsigned</span> <span class="macmade-code-keyword">long</span> binary )</code><br />
 <code class="macmade-source">{</code><br />
 <code class="macmade-source">    <span class="macmade-code-comment">/* Gets the sign field */</span></code><br />
 <code class="macmade-source">    <span class="macmade-code-comment">/* Bit 0, left to right */</span></code><br />
 <code class="macmade-source">    <span class="macmade-code-ctag">boolean</span> sign           = binary &gt;&gt; 31;</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-comment">/* Gets the exponent field */</span></code><br />
 <code class="macmade-source">    <span class="macmade-code-comment">/* Bits 1 to 8, left to right */</span></code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">unsigned</span> <span class="macmade-code-keyword">char</span> exp      = ( ( binary &gt;&gt; 23 ) &amp; 0xFF );</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-comment">/* Gets the mantissa field */</span></code><br />
 <code class="macmade-source">    <span class="macmade-code-comment">/* Bits 9 to 32, left to right */</span></code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">unsigned</span> <span class="macmade-code-keyword">long</span> mantissa = ( binary &amp; 0x7FFFFF );</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-comment">/* Storage for the return value */</span></code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">float</span> floatValue       = 0;</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-comment">/* Counter */</span></code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">signed</span> <span class="macmade-code-keyword">int</span> i           = 0;</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-comment">/* Checks the values of the exponent and the mantissa fields to handle special numbers */</span></code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">if</span>( exp == 0 &amp;&amp; mantissa == 0 ) {</code></p>
<p> <code class="macmade-source">        <span class="macmade-code-comment">/* Zero - No need for a computation even if it can be considered as a denormalized number */</span></code><br />
 <code class="macmade-source">        <span class="macmade-code-keyword">return</span> 0;</code></p>
<p> <code class="macmade-source">    } <span class="macmade-code-keyword">else</span> <span class="macmade-code-keyword">if</span>( exp == 255 &amp;&amp; mantissa == 0 ) {</code></p>
<p> <code class="macmade-source">        <span class="macmade-code-comment">/* Infinity */</span></code><br />
 <code class="macmade-source">        <span class="macmade-code-keyword">return</span> 0;</code></p>
<p> <code class="macmade-source">    } <span class="macmade-code-keyword">else</span> <span class="macmade-code-keyword">if</span>( exp == 255 &amp;&amp; mantissa != 0 ) {</code></p>
<p> <code class="macmade-source">        <span class="macmade-code-comment">/* Not a number */</span></code><br />
 <code class="macmade-source">        <span class="macmade-code-keyword">return</span> 0;</code></p>
<p> <code class="macmade-source">    } <span class="macmade-code-keyword">else</span> <span class="macmade-code-keyword">if</span>( exp == 0 &amp;&amp; mantissa != 0 ) {</code></p>
<p> <code class="macmade-source">        <span class="macmade-code-comment">/* Denormalized number - Exponent is fixed to -126 */</span></code><br />
 <code class="macmade-source">        exp = -126;</code></p>
<p> <code class="macmade-source">    } <span class="macmade-code-keyword">else</span> {</code></p>
<p> <code class="macmade-source">        <span class="macmade-code-comment">/* Computes the real exponent */</span></code><br />
 <code class="macmade-source">        exp      = exp - 127;</code></p>
<p> <code class="macmade-source">        <span class="macmade-code-comment">/* Adds the implicit bit to the mantissa */</span></code><br />
 <code class="macmade-source">        mantissa = mantissa | 0x800000;</code><br />
 <code class="macmade-source">    }</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-comment">/* Process the 24 bits of the mantissa */</span></code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">for</span>( i = 0; i &gt; -24; i-- ) {</code></p>
<p> <code class="macmade-source">        <span class="macmade-code-comment">/* Checks if the current bit is set */</span></code><br />
 <code class="macmade-source">        <span class="macmade-code-keyword">if</span>( mantissa &amp; ( 1 &lt;&lt; ( i + 23 ) ) ) {</code></p>
<p> <code class="macmade-source">            <span class="macmade-code-comment">/* Adds the value for the current bit */</span></code><br />
 <code class="macmade-source">            <span class="macmade-code-comment">/* This is done by computing two raised to the power of the exponent plus the bit position */</span></code><br />
 <code class="macmade-source">            <span class="macmade-code-comment">/* (negative if it's after the implicit bit, as we are using scientific notation) */</span></code><br />
 <code class="macmade-source">            floatValue += ( <span class="macmade-code-keyword">float</span> )<span class="macmade-code-ctag">pow</span>( 2, i + exp );</code><br />
 <code class="macmade-source">        }</code><br />
 <code class="macmade-source">    }</code></p>
<p> <code class="macmade-source">    <span class="macmade-code-comment">/* Returns the final float value */</span></code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">return</span> ( sign == <span class="macmade-code-keyword">FALSE</span> ) ? floatValue : -floatValue;</code><br />
 <code class="macmade-source">}</code></p>
<p> <code class="macmade-source"><span class="macmade-code-comment">/**</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * C main() function</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * </span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> * @return  int     The exit status</span></code><br />
 <code class="macmade-source"><span class="macmade-code-comment"> */</span></code><br />
 <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-ctag">printf</span>( <span class="macmade-code-string">"%f\n"</span>, <span class="macmade-code-ctag">binaryToFloat</span>( 0x40B80000 ) );</code><br />
 <code class="macmade-source">    <span class="macmade-code-keyword">return</span> <span class="macmade-code-ctag">EXIT_SUCCESS</span>;</code><br />
 <code class="macmade-source">}</code> </div>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2009/09/24/comprendre-les-nombres-a-virgule-flottante/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>Découvrez l’équipe de netinfluence</title>
		<link>http://blog.netinfluence.com/2009/08/17/decouvrez-equipe-de-netinfluence/</link>
		<comments>http://blog.netinfluence.com/2009/08/17/decouvrez-equipe-de-netinfluence/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 08:58:00 +0000</pubDate>
		<dc:creator>sandrine</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[Développement]]></category>
		<category><![CDATA[équipe]]></category>
		<category><![CDATA[jean szabo]]></category>
		<category><![CDATA[marie girardet]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[netinfluence]]></category>
		<category><![CDATA[présentation]]></category>
		<category><![CDATA[sandrine szabo]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[traffic manager]]></category>

		<guid isPermaLink="false">http://blog.netinfluence.ch/?p=76</guid>
		<description><![CDATA[Nous sommes heureux d&#8217;accueillir un nouveau membre dans notre équipe. Et à cette occasion, il m&#8217;a semblé nécessaire de présenter la totalité des membres qui composent netinfluence. Il est vrai que l&#8217;on voit 3 têtes sur le site web &#8211; celle de Jean, Marc et moi &#8211; mais ce sont juste les responsables des 3 unités : Développement, Design et Marketing. Ces 3 pôles regroupent désormais 7 personnes. Nous devons notre excellence et notre réputation à chacun d&#8217;entre eux et bien que leurs rôle soient différents, ils comptent tous énormément et contribuent, chacun à leur façon à ce que nous sommes aujourd&#8217;hui. Emilien dit &#8220;padawan&#8221; &#8211; Expert iPhone &#38; Zend PHP Emilien est notre premier collaborateur, il a donc une place [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float: right; margin: 0 0 1em 1em;" title="nabsistant.png, août 2009" src="/public/Sandrine/nabsistant.png" alt="nabsistant.png" />Nous sommes heureux d&#8217;accueillir un nouveau membre dans notre équipe.  Et à cette occasion, il m&#8217;a semblé nécessaire de présenter la totalité des membres qui composent netinfluence.  Il est vrai que l&#8217;on voit 3 têtes sur le site web &#8211; celle de Jean, Marc et moi &#8211; mais ce sont juste les responsables des 3 unités : Développement, Design et Marketing. Ces 3 pôles regroupent désormais 7 personnes.</p>
<p>Nous devons notre excellence et notre réputation à chacun d&#8217;entre eux et bien que leurs rôle soient différents, ils comptent tous énormément et contribuent, chacun à leur façon à ce que nous sommes aujourd&#8217;hui.</p>
<p><strong>Emilien dit &#8220;padawan&#8221; &#8211; Expert iPhone &amp; Zend PHP</strong><br />
<img style="float: left; margin: 0 1em 1em 0;" title="photo d'émilien vuillaume" src="/public/Sandrine/emilien.png" alt="emilien.png" />Emilien est notre premier collaborateur, il a donc une place spéciale dans notre équipe.<br />
C&#8217;est un peu notre&#8221;apprenti jedi&#8221;.  Bien qu&#8217;il ait clairement un niveau d&#8217;expertise &#8220;senior&#8221;, il ne sait pas encore que la force est en lui <img src='http://blog.netinfluence.com/wp-content/plugins/smilies-themer/Silk/emoticon_wink.png' alt=';-)' class='wp-smiley' /> <br />
Il programme comme un poète et met tellement de coeur et de talent dans son code que c&#8217;en est beau. PHP master, il a appris Zend en quelques mois seulement, passé ses deux certifications sans sourciller, haut la main. Object oriented, javascript poet, il s&#8217;est pris de passion pour l&#8217;iPhone dont il maîtrise la programmation.<br />
Depuis ses formations à Paris, son voyage à la WWDC d&#8217;Apple et son nouvel écran 24&#8243;, il ne jure plus que par Mac.<br />
<strong>Rejoindre son réseau ou le contacter :</strong> <a href="http://www.linkedin.com/in/emilienvuillaume"><img title="linkedin émilien" src="/public/Sandrine/linkedin.png" alt="linkedin.png" /></a> <a href="http://twitter.com/evuillaume"><img title="twitter émilien" src="/public/Sandrine/twitter.png" alt="twitter.png" /></a> <a href="skype:emilien.vuillaume?add"><img title="skype émilien" src="/public/Sandrine/skype.png" alt="skype.png" /></a> <a href="http://www.facebook.com/home.php?#/emilien.vuillaume?ref=ts"><img title="facebook émilien" src="/public/Sandrine/facebook.png" alt="facebook.png" /></a> <a href="mailto:%65%6d%69%6c%69%65%6e%40%6e%65%74%69%6e%66%6c%75%65%6e%63%65%2e%63%68"><img title="envoyer un mail à émilien" src="/public/Sandrine/mail.png" alt="mail.png" /></a></p>
<p><strong>Julien dit &#8220;obiwan&#8221; &#8211; Expert Zend PHP, Magento &amp; Typo3</strong><br />
<img style="float: left; margin: 0 1em 1em 0;" title="photo de julien dunand" src="/public/Sandrine/julien.png" alt="julien.png" />Il ne se laissera impressionner par aucune difficulté.  Son sang froid et sa maîtrise ainsi que sa curiosité font qu&#8217;il absorbe tout, lit tout, test tout et apprend en continue.<br />
Il s&#8217;est certifié en ZEND PHP et Zend Framwork en deux coups de cuillère à pot, une simple formalité, ce qui a confirmé ce que nous avions déjà repéré, son excellence.<br />
Structuré, vif, il sait s&#8217;atteler a de très gros développements avec une vitesse incroyable. Doté d&#8217;un très bon sens du contact il sait également gérer des projets avec talent et organisation. Il est précis, performant et dispose de réels talents d&#8217;écoute. PHP master bien entendu, il a également une longue expérience en CMS et en ecommerce ce qui lui a rapidement permis d&#8217;accroître son expertise autour de Typo3 et de MAGENTO pour lequel il écrit des extensions et dont il est l&#8217;expert chez nous.<br />
Gadgetophile, comme nous tous, il s&#8217;essaie maintenant au développement iPhone;-)<br />
<strong>Rejoindre son réseau ou le contacter :</strong> <a href="http://www.linkedin.com/in/juliendunand"><img title="linkedin julien" src="/public/Sandrine/linkedin.png" alt="linkedin.png" /></a> <a href="http://twitter.com/tusbru"><img title="twitter julien" src="/public/Sandrine/twitter.png" alt="twitter.png" /></a> <a href="skype:tusbrissimo?add"><img title="skype julien" src="/public/Sandrine/skype.png" alt="skype.png" /></a> <a href="http://www.facebook.com/home.php?#/tusbru?ref=ts"><img title="facebook julien" src="/public/Sandrine/facebook.png" alt="facebook.png" /></a> <a href="mailto:%6a%75%6c%69%65%6e%40%6e%65%74%69%6e%66%6c%75%65%6e%63%65%2e%63%68"><img title="envoyer un mail à julien" src="/public/Sandrine/mail.png" alt="mail.png" /></a></p>
<p><strong>Jean-David dit &#8220;Macmade&#8221; &#8211; Expert Typo3, PHP</strong><br />
<img style="float: left; margin: 0 1em 1em 0;" title="photo de macmade" src="/public/Sandrine/jean-david.png" alt="jean-david.png" />Macmade est un développeur très reconnu et apprécié par la communauté Typo3. Il est à l&#8217;origine de plus de 30 extensions, dont certaines sont la base de nombreux développements de la communauté.  Fan d&#8217;Apple dont il tire son pseudo, développeur cocoa, il est également expert PHP (se prépare à quelques certifications d&#8217;ailleurs dans le domaine) et se lance désormais dans l&#8217;iPhone.<br />
Réservé et très humble, il a une conscience exacerbée de l&#8217;Open source et du partage.  Créateur discret et efficace, il a su au fil du temps se créer un réseau et une réputation incroyable.  Ce sont du reste ces valeurs que nous avons en commun &#8211; la passion, l&#8217;excellence, le partage &#8211; qui nous ont permis de nous rapprocher et de lui donner envie de rejoindre notre équipe.<br />
<strong>Rejoindre son réseau ou le contacter :</strong> <a href="http://www.linkedin.com/in/macmade"><img title="linkedin de jean david" src="/public/Sandrine/linkedin.png" alt="linkedin.png" /></a> <a href="skype:macmade?add"><img title="skype jean david" src="/public/Sandrine/skype.png" alt="skype.png" /></a> <a href="http://www.facebook.com/home.php?#/macmade?ref=ts"><img title="facebook jean david" src="/public/Sandrine/facebook.png" alt="facebook.png" /></a> <a href="mailto:%6a%65%61%6e%2d%64%61%76%69%64%40%6e%65%74%69%6e%66%6c%75%65%6e%63%65%2e%63%68"><img title="envoyer un mail à jean david" src="/public/Sandrine/mail.png" alt="mail.png" /></a></p>
<p><strong>Jean, &#8220;Maître Yoda&#8221; &#8211; Expert Zend PHP &amp; Typo3 &gt; responsable du pôle Développement</strong><br />
<img style="float: left; margin: 0 1em 1em 0;" title="photo de jean szabo" src="/public/Sandrine/jean.png" alt="jean.png" />Jean est au centre de cette équipe technique.  Il lui insufle la direction et la cadence.  Soucieux de l&#8217;expérience utilisateur, sa priorité a toujours été de rendre les clients satisfaits.  Il dispose d&#8217;une écoute et d&#8217;une capacité de compréhension et d&#8217;empathie incroyable.<br />
Il est le pivot des mondes techniques, design et marketing car il a la capacité a comprendre le meilleur de tous ces mondes et à les mettre en relation les uns avec les autres.<br />
Simple et très accessible, il donne de son temps pour développer cette équipe et mener à bien les projets.<br />
Respecté pour son expertise PHP et Typo3, il co-dirige netinfluence avec moi et en est incontestablement le ciment.<br />
<strong>Rejoindre son réseau ou le contacter :</strong> <a href="http://www.linkedin.com/in/jeanszabo"><img title="linkedin jean" src="/public/Sandrine/linkedin.png" alt="linkedin.png" /></a> <a href="http://twitter.com/nitrobear"><img title="twitter jean" src="/public/Sandrine/twitter.png" alt="twitter.png" /></a> <a href="skype:nitrobear?add"><img title="skype jean" src="/public/Sandrine/skype.png" alt="skype.png" /></a> <a href="http://www.facebook.com/jean.szabo?ref=ts"><img title="facebook de jean" src="/public/Sandrine/facebook.png" alt="facebook.png" /></a> <a href="mailto:%6a%65%61%6e%40%6e%65%74%69%6e%66%6c%75%65%6e%63%65%2e%63%68"><img title="envoyer un mail à jean" src="/public/Sandrine/mail.png" alt="mail.png" /></a></p>
<p><strong>Marc &#8220;Design Master&#8221; &#8211; Design Director : responsable du pôle UI et Design</strong><br />
<img style="float: left; margin: 0 1em 1em 0;" title="photo de marc grand d'hauteville" src="/public/Sandrine/marc.png" alt="marc.png" />Marc est apparu sur notre route il y a 3 ans.  Il nous a impressionné immédiatement, non pas par les questions bizarre qu&#8217;il posait (et si vous étiez un animal?) mais par son pragmatisme et ses connaissances du web.  Il ne fait pas du design pour du design.  Il donne vie à une identité élégante et représentative dans laquelle les clients se reconnaissent si bien qu&#8217;ils ont du mal à se souvenir comment c&#8217;était avant.<br />
C&#8217;est un designer exceptionnel, un créatif incroyable et surtout un homme profond.  Il s&#8217;intéresse à comprendre.  Il est curieux, ouvert, très bizarre aussi, il vous posera des questions destabilisantes et se murera dans un silence créatif (enfin on suppose :D) avant de vous suggérer exactement ce que vous cherchiez, l&#8217;idée qu&#8217;il vous faut, en toute simplicité.<br />
Son talent créatif ne se fait jamais aux détriments des contraintes techniques.  Les solutions imaginées sont agréables, toujours disruptives.<br />
Sa force ? Être capable de voir ce que l&#8217;on ne montre pas, d&#8217;entendre ce que l&#8217;on ne dit pas, et de se projeter loin, très loin.<br />
<strong>Rejoindre son réseau ou le contacter :</strong> <a href="http://www.linkedin.com/in/marcgdh"><img title="linkedin de marc" src="/public/Sandrine/linkedin.png" alt="linkedin.png" /></a> <a href="http://twitter.com/mgdh"><img title="twitter marc" src="/public/Sandrine/twitter.png" alt="twitter.png" /></a> <a href="skype:marcgdh?add"><img title="skype marc" src="/public/Sandrine/skype.png" alt="skype.png" /></a> <a href="http://www.facebook.com/profile.php?id=588075748&amp;ref=ts#/profile.php?id=588075748&amp;v=info&amp;viewas=676531103&amp;ref=ts"><img title="facebook marc" src="/public/Sandrine/facebook.png" alt="facebook.png" /></a> <a href="mailto:%6d%61%72%63%40%6e%65%74%69%6e%66%6c%75%65%6e%63%65%2e%63%68"><img title="envoyer un mail à marc" src="/public/Sandrine/mail.png" alt="mail.png" /></a></p>
<p><strong>Marie &#8220;Madawan&#8221; &#8211; Traffic Manager</strong><br />
<img style="float: left; margin: 0 1em 1em 0;" title="photo de marie girardet" src="/public/Sandrine/marie.png" alt="marie.png" />Comme padawan était déjà pris, Marie est Madawan.  C&#8217;est un petit surnom qui lui a été donné parce que, comme émilien, elle a beaucoup de potentiel, qu&#8217;elle apprend à découvrir chaque jour.<br />
Marie gère les campagnes Adwords ou Facebook, les campagnes d&#8217;emailing ainsi que tout ce qui concerne analytics et le référencement.  Son rôle consiste à nous aider et à aider nos clients à amener du traffic de qualité vers nos sites internet.<br />
Certifiée Analytics, elle s&#8217;est prise de passion pour le SEO / SEM (search engine optimization / search engine marketing) et prépare actuellement d&#8217;autres certifications comme celle d&#8217;adwords.<br />
<strong>Rejoindre son réseau ou la contacter :</strong> <a href="http://www.linkedin.com/in/mariegirardet"><img title="linkedin marie" src="/public/Sandrine/linkedin.png" alt="linkedin.png" /></a> <a href="http://twitter.com/mgirardet"><img title="twitter marie" src="/public/Sandrine/twitter.png" alt="twitter.png" /></a> <a href="skype:marie.girardet?add"><img title="skype marie" src="/public/Sandrine/skype.png" alt="skype.png" /></a> <a href="http://www.facebook.com/marie.girardet?ref=ts"><img title="facebook marie" src="/public/Sandrine/facebook.png" alt="facebook.png" /></a> <a href="mailto:%6d%61%72%69%65%40%6e%65%74%69%6e%66%6c%75%65%6e%63%65%2e%63%68"><img title="envoyer un mail à marie" src="/public/Sandrine/mail.png" alt="mail.png" /></a></p>
<p><strong>Me, myself and I &#8211; Marketing Master : CEO et responsable du pôle marketing communication</strong><br />
<img style="float: left; margin: 0 1em 1em 0;" title="photo de sandrine szabo" src="/public/Sandrine/sandrine.png" alt="sandrine.png" />Se décrire est la chose la plus narcissique et la plus difficile à faire. J&#8217;en ferais probablement trop ou pas assez, alors j&#8217;espère que vous me pardonnerez.<br />
Fille d&#8217;entrepreneur, j&#8217;avais juré que l&#8217;on ne m&#8217;y prendrais jamais.  Je n&#8217;ai peur ni des efforts, ni des sacrifices, mais je voyais la direction d&#8217;entreprise comme un travail de solitaire dont je ne voulais pas.  Je me suis toujours impliquée corps et âmes dans mon job à tel point que j&#8217;avais presque un sentiment fusionnel avec mes employeurs, mais n&#8217;ai pas toujours obtenu un juste retour de reconnaissance.  Le déclic pour moi c&#8217;est une série de choses difficile dont des managers minables.<br />
Manager des gens ne doit pas signifier écraser des gens.  Avoir des clients ne doit pas signifier profiter de ses clients, les essorer.<br />
Je voulais faire du web, du marketing et voyant que personne ne me donnait ma chance, je me suis dit que la chance cela se provoquait.  Le marketing est un domaine passionnant et qui plus est en complète révolution, grâce au net.  Je sentais qu&#8217;une nouvelle génération de marketeurs émergeait, et je voulais en être.<br />
Le web 2.0 a permis de faire jaillir un rapport équitable entre les clients et les corporations, les collaborateurs et les employeurs.  C&#8217;est un nouvel univers, basé sur la conversation qui s&#8217;ouvre à nous.  Il est riche de relations humaines.  Il nécessite une nouvelle race d&#8217;experts cross-expertises.  Fini les marketeurs dans leurs tours d&#8217;ivoire.  Fini les développeurs devant des écrans.  Il faut une nouvelle générations d&#8217;experts ouverts, passionnés, curieux et surtout humbles dans leur capacité à écouter tout ce qu&#8217;ils ne savent pas encore.  Car internet évolue tous les jours, donc nous devons aussi nous remettre en question chaque jour. Je me sens parfaitement à l&#8217;aise dans mon rôle de marketeur et de connecteur.  Au sein de netinfluence j&#8217;aide les entreprises à accroître leur influence online et à comprendre les enjeux de cette révolution.<br />
<strong>Rejoindre son réseau ou la contacter :</strong> <a href="http://www.linkedin.com/in/sandrineszabo"><img title="linkedin de sandrine" src="/public/Sandrine/linkedin.png" alt="linkedin.png" /></a> <a href="http://twitter.com/sandrineszabo"><img title="twitter sandrine" src="/public/Sandrine/twitter.png" alt="twitter.png" /></a> <a href="skype:sandrine.szabo?add"><img title="skype sandrine" src="/public/Sandrine/skype.png" alt="skype.png" /></a> <a href="http://www.facebook.com/sandrine.szabo?ref=ts"><img title="facebook sandrine" src="/public/Sandrine/facebook.png" alt="facebook.png" /></a> <a href="mailto:%73%61%6e%64%72%69%6e%65%40%6e%65%74%69%6e%66%6c%75%65%6e%63%65%2e%63%68"><img title="envoyer un mail à sandrine" src="/public/Sandrine/mail.png" alt="mail.png" /></a></p>
<p>netinfluence est donc une entreprise nouvelle génération qui reflète un peu de chacun d&#8217;entre nous.  Notre ADN se compose de curiosité, de passion, d&#8217;anticonformisme et d&#8217;audace. Si ce que nous sommes et ce que nous faisons &#8211; Aider les entreprises à améliorer leur influence online &#8211; vous intéresse, nous serons ravis de faire votre connaissance et de voir comment nous pouvons vous aider.<br />
Nous publions régulièrement du contenu dans ce blog mais aussi sur le twitter de netinfluence et dans delicious, alors n&#8217;hésitez pas à nous suivre aussi ici : <a href="http://twitter.com/netinfluence"><img title="twitter netinfluence" src="/public/Sandrine/twitter.png" alt="twitter.png" /></a> <a href="http://delicious.com/netinfluence"><img title="delicious netinfluence" src="/public/Sandrine/delicious.png" alt="delicious.png" /></a> <a href="http://feeds2.feedburner.com/netinfluence_blog"><img title="s'abonner au blog" src="/public/Sandrine/rss.png" alt="rss.png" /></a> <a href="http://www.flickr.com/photos/netinfluence"><img title="flickr de netinfluence" src="/public/Sandrine/flickr.png" alt="flickr.png" /></a></p>
<!-- PHP 5.x -->]]></content:encoded>
			<wfw:commentRss>http://blog.netinfluence.com/2009/08/17/decouvrez-equipe-de-netinfluence/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

