diff options
Diffstat (limited to 'fr-fr')
-rw-r--r-- | fr-fr/csharp-fr.html.markdown | 812 | ||||
-rw-r--r-- | fr-fr/haskell.html.markdown | 1 | ||||
-rw-r--r-- | fr-fr/objective-c-fr.html.markdown | 528 | ||||
-rw-r--r-- | fr-fr/python-fr.html.markdown | 2 |
4 files changed, 1342 insertions, 1 deletions
diff --git a/fr-fr/csharp-fr.html.markdown b/fr-fr/csharp-fr.html.markdown new file mode 100644 index 00000000..c1641716 --- /dev/null +++ b/fr-fr/csharp-fr.html.markdown @@ -0,0 +1,812 @@ +--- +language: c# +contributors: + - ["Irfan Charania", "https://github.com/irfancharania"] + - ["Max Yankov", "https://github.com/golergka"] + - ["Melvyn Laïly", "http://x2a.yt"] + - ["Shaun McCarthy", "http://www.shaunmccarthy.com"] +translators: + - ["Olivier Hoarau", "https://github.com/Olwaro"] +filename: LearnCSharp.cs +lang: fr-fr +--- + +C# est un langage de programmation orienté objet à typage fort qui permet aux développeurs de créer une grande variété d'applications fiables et robustes s'appuyant sur le framework .NET. + +[Plus d'infos](http://msdn.microsoft.com/fr-fr/library/67ef8sbd.aspx) + +```c# +// Les commentaires sur une seule ligne commencent par // +/* +Les +commentaires +multi-lignes +ressemblent +à +ceci +*/ +/// <summary> +/// Ceci est un commentaire de documentation XML +/// </summary> + +// Importez des namespaces avec l'instruction 'using' +using System; +using System.Collections.Generic; +using System.Data.Entity; +using System.Dynamic; +using System.Linq; +using System.Linq.Expressions; +using System.Net; +using System.Threading.Tasks; + +// Définit la portée du code pour une meilleure organisation +namespace Learning +{ + // Chaque fichier .cs devrait au moins contenir une classe avec le même nom + // que celui du fichier. Ce n'est pas une obligation mais c'est mieux ! + public class LearnCSharp + { + // LES BASES - si vous avez déjà de l'expérience en Java ou C++ + // passez directement à la partie FONCTIONNALITÉS INTERÉSSANTES + public static void Syntax() + { + // Utilisez Console.WriteLine pour écrire sur la sortie + Console.WriteLine("Hello World"); + Console.WriteLine( + "Entier: " + 10 + + " Double: " + 3.14 + + " Booleen: " + true); + + // Pour omettre le retour à la ligne : Console.Write + Console.Write("Hello "); + Console.Write("World"); + + /////////////////////////////////////////////////// + // Types et Variables + // Déclarez une variable avec la syntaxe <type> <nom> + /////////////////////////////////////////////////// + + // Sbyte - Entier signé sur 8 bits + // (-128 <= sbyte <= 127) + sbyte fooSbyte = 100; + + // Byte - Entier non-signé sur 8 bits + // (0 <= byte <= 255) + byte fooByte = 100; + + // Short - Entier sur 16 bits + // Signé - (-32,768 <= short <= 32,767) + // Non-signé - (0 <= ushort <= 65,535) + short fooShort = 10000; + ushort fooUshort = 10000; + + // Int - Entier sur 32 bits + int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647) + uint fooUint = 1; // (0 <= uint <= 4,294,967,295) + + // Long - Entier sur 64 bits + long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) + ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615) + // Par défaut le type d'un littéral entier est int ou uint + // on ajoute 'L' pour spécifier la création d'un long + + // Double - Réel sur 64 bits en virgule flottante (norme IEEE 754) + double fooDouble = 123.4; // Precision : 15-16 chiffres + + // Float - Réel sur 32 bits en virgule flottante (norme IEEE 754) + float fooFloat = 234.5f; // Precision : 7 chiffres + // Par défaut le type d'un littéral réel est double + // on ajoute 'f' pour spécifier la création d'un float + + // Decimal - Type de donnée numérique sur 128 bits, fournit une plus + // grande précision et une plage de valeurs réduite. + // Approprié aux calculs financiers et monétaires + decimal fooDecimal = 150.3m; + + // Booléen - vrai / faux + bool fooBoolean = true; // ou false + + // Char - Un unique caractère Unicode sur 16 bits + char fooChar = 'A'; + + // String -- contrairement aux types précédents qui sont des types valeurs, + // string est un type référence. Il peut donc avoir la valeur null + string fooString = "\"échappement\" de guillemets et ajout de \n (nouvelle ligne) et de \t (tabulation)"; + Console.WriteLine(fooString); + + // Il est possible d'accéder à chaque caractère d'une chaîne de caractères via son index + char charFromString = fooString[1]; // 'é' + // une chaîne de caractères est immuable : impossible de faire fooString[1] = 'X'; + + // Comparaison de chaînes de caractères avec la culture courrante en ignorant la casse + string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase); + + // Formatage + string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2); + + // Dates et formatage + DateTime fooDate = DateTime.Now; + Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy")); + + // Il est possible d'étaler une chaîne de caractères sur plusieurs lignes avec le symbole @. + // Pour échapper " utilisez "" + string bazString = @"Voici quelques trucs +sur une nouvelle ligne! ""Wow!"", quel style"; + + // Utilisez const ou read-only pour rendre une variable immuable. + // Les valeurs constantes sont calculées au moment de la compilation + const int HOURS_I_WORK_PER_WEEK = 9001; + + /////////////////////////////////////////////////// + // Structures de données + /////////////////////////////////////////////////// + + // Tableaux - indexé à partir de zéro + // La taille d'un tableau doit être décidée à la déclaration + // La syntaxe pour déclarer un tableau est la suivante : + // <type>[] <nom> = new <type>[<taille>] + int[] intArray = new int[10]; + + // Une autre méthode de déclaration et d'initialisation + int[] y = { 9000, 1000, 1337 }; + + // Indexer un tableau - Accéder à un élément + Console.WriteLine("intArray à 0: " + intArray[0]); + // Les tableaux sont muables. + intArray[1] = 1; + + // Listes + // Elles sont plus souvent utilisées que les tableaux car plus souples + // La syntaxe pour déclarer une liste est la suivante : + // List<type> <nom> = new List<type>(); + List<int> intList = new List<int>(); + List<string> stringList = new List<string>(); + List<int> z = new List<int> { 9000, 1000, 1337 }; // intialisation + // Les <> indiquent un type générique + // Pus d'info dans la partie FONCTIONNALITÉS INTERÉSSANTES + + // Les éléments d'une liste ne sont pas null par défaut + // Il faut ajouter une valeur avant d'y accéder par index + intList.Add(1); + Console.WriteLine("intList à 0: " + intList[0]); + + // Autres structures de données à étudier : + // Stack/Queue (Pile/File) + // Dictionary (une implémentation de hash map) + // HashSet (représente un ensemble) + // Collections en lecture seule + // Tuple (.Net 4+) + + /////////////////////////////////////// + // Opérateurs + /////////////////////////////////////// + Console.WriteLine("\n->Opérateurs"); + + int i1 = 1, i2 = 2; // Raccourci pour des déclarations multiples + + // Arithmétique classique + Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3 + + // Modulo + Console.WriteLine("11%3 = " + (11 % 3)); // => 2 + + // Opérateurs de comparaison + Console.WriteLine("3 == 2? " + (3 == 2)); // => False + Console.WriteLine("3 != 2? " + (3 != 2)); // => True + Console.WriteLine("3 > 2? " + (3 > 2)); // => True + Console.WriteLine("3 < 2? " + (3 < 2)); // => False + Console.WriteLine("2 <= 2? " + (2 <= 2)); // => True + Console.WriteLine("2 >= 2? " + (2 >= 2)); // => True + + // Opérateurs bit à bit ! + /* + ~ Compément unaire + << Décalage à gauche + >> Décalage à droite + & ET logique + ^ OU exclusif + | OU inclusif + */ + + // Incrémentations + int i = 0; + Console.WriteLine("\n->Inc/Dec-rementation"); + Console.WriteLine(i++); //i = 1. Post-Incrémentation + Console.WriteLine(++i); //i = 2. Pre-Incrémentation + Console.WriteLine(i--); //i = 1. Post-Decrémentation + Console.WriteLine(--i); //i = 0. Pre-Decrémentation + + /////////////////////////////////////// + // Structures de contrôle + /////////////////////////////////////// + Console.WriteLine("\n->Structures de contrôle"); + + // Structure conditionnelle + int j = 10; + if (j == 10) + { + Console.WriteLine("Je serai affiché"); + } + else if (j > 10) + { + Console.WriteLine("Pas moi"); + } + else + { + Console.WriteLine("Moi non plus"); + } + + // Opérateur ternaire + // Un simple if/else peut s'écrire : + // <condition> ? <valeur si true> : <valeur si false> + string isTrue = (true) ? "True" : "False"; + + // Boucle while + int fooWhile = 0; + while (fooWhile < 100) + { + // 100 passages, de 0 à 99 + fooWhile++; + } + + // Boucle Do While + int fooDoWhile = 0; + do + { + // 100 passages, de 0 à 99 + fooDoWhile++; + } while (fooDoWhile < 100); + + // Boucle for + // Structure : for(<etat_initial>; <condition>; <pas>) + for (int fooFor = 0; fooFor < 10; fooFor++) + { + // 10 passages, de 0 à 9 + } + + // La boucle foreach + // Structure : foreach(<type_iterateur> <nom_iterateur> in <enumerable>) + // Cette boucle est utilisable sur des objets implémentant IEnumerable ou IEnumerable<T> + // Toutes les collections du framework .NET (Tableaux, Listes, ...) implémentent ces interfaces. + // (Notez que dans l'exemple suivant .ToCharArray() peut être omit car + // string implémente IEnumerable) + foreach (char character in "Hello World".ToCharArray()) + { + //Itération sur chaque caractère + } + + // La structure Switch Case + // Un switch fonctionne avec les types : byte, short, char et int. + // Les enums sont aussi supportés ainsi que les chaînes de caractères et quelques + // classes spéciales basées sur les types primitifs : Character, Byte, Short et Integer. + int mois = 3; + string moisString; + switch (mois) + { + case 1: + moisString = "Janvier"; + break; + case 2: + moisString = "Février"; + break; + case 3: + moisString = "Mars"; + break; + + // Vous pouvez assigner plus d'un 'case' à une action + // Mais vous ne pouvez pas ajouter une action sans 'break' avant un 'case' + // (pour ce faire, il faudrait ajouter explicitement un 'goto case x') + case 6: + case 7: + case 8: + moisString = "C'est l'été!"; + break; + default: + moisString = "Un autre mois oO"; + break; + } + + /////////////////////////////////////// + // conversion de type de donnée et transtypage + /////////////////////////////////////// + + // conversion de string vers int + // lève une exception en cas d'erreur + int.Parse("123"); //retourne la valeur entière de "123" + + // TryParse affecte la valeur par défaut du type en cas d'erreur + // dans ce cas : 0 + int tryInt; + if (int.TryParse("123", out tryInt)) // La fonction retourne un booléen + Console.WriteLine(tryInt); // => 123 + + // conversion d'un entier vers une chaîne de caractères + // La classe Convert possède plusieurs méthodes pour faciliter la conversion + Convert.ToString(123); + // ou + tryInt.ToString(); + } + + /////////////////////////////////////// + // CLASSES - voir les définitions à la fin du fichier + /////////////////////////////////////// + + public static void Classes() + { + // voir les déclarations à la fin du fichier + + // Utilisez 'new' pour instancier une classe + Bicycle trek = new Bicycle(); + + // Appel des méthodes de l'objet + trek.SpeedUp(3); // Il est toujours bon d'utiliser des accesseurs + trek.Cadence = 100; + + // Affichage de la valeur de retour d'une méthode. + Console.WriteLine("trek info: " + trek.Info()); + + // Instanciation d'un nouveau PennyFarthing + PennyFarthing funbike = new PennyFarthing(1, 10); + Console.WriteLine("funbike info: " + funbike.Info()); + + Console.Read(); + } + + // POINT D'ENTRÉE - Une application console doit avoir une méthode main comme point d'entrée + public static void Main(string[] args) + { + OtherInterestingFeatures(); + } + + // + // FONCTIONNALITÉS INTÉRÉSSANTES + // + + // SIGNATURE DE METHODE + public // Visibilité + static // Permet un appel direct par la classe (sans instanciation) + int // Type de retour, + MethodSignatures( + int maxCount, // Premier paramètre, de type int + int count = 0, // Valeur par défaut si aucun argument n'est passé + int another = 3, + params string[] otherParams // Capture tous les arguments passés à la méthode + ) + { + return -1; + } + + // Des méthodes peuvent avoir le même nom tant que leur signature est unique + public static void MethodSignature(string maxCount) + { + } + + // TYPE GÉNÉRIQUE + + // Les types TKey et TValue sont spécifiés par l'utilisateur lors de l'appel de la fonction + // Cette méthode émule SetDefaut de Python + public static TValue SetDefault<TKey, TValue>( + IDictionary<TKey, TValue> dictionary, + TKey key, + TValue defaultItem) + { + TValue result; + if (!dictionary.TryGetValue(key, out result)) + return dictionary[key] = defaultItem; + return result; + } + + // Vous pouvez limiter les types autorisés + public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int> + { + // Nous sommes sûrs de pouvoir itérer, car T implémente IEnumerable<int> + foreach (var item in toPrint) + // Item sera de type int + Console.WriteLine(item.ToString()); + } + + public static void OtherInterestingFeatures() + { + // PARAMÈTERES OPTIONNELS + MethodSignatures(3, 1, 3, "Des", "Paramètres", "En plus"); + MethodSignatures(3, another: 3); // affectation explicite, les autres + // paramètres ont la valeur par défaut + + // MÉTHODE D'EXTENSION + int i = 3; + i.Print(); // Définit plus bas + + // TYPES NULLABLE - idéal pour les interactions avec une base de données ou pour les valeurs de retour + // Tous les types valeurs peuvent être rendus nullable en les suffixant par '?' + // <type>? <nom> = <value> + int? nullable = null; // raccourci pour Nullable<int> + Console.WriteLine("Nullable variable: " + nullable); + bool hasValue = nullable.HasValue; // retourne vrai si la valeur n'est pas null + + // ?? est un sucre syntaxique pour spécifier une valeur par défaut + // au cas ou une autre valeur serait nulle + int notNullable = nullable ?? 0; // 0 + + // VARIABLES IMPLICITEMENT TYPÉES - vous pouvez laisser le compilateur deviner le type d'une variable + var magic = "magic est de type string à la compilation. On a toujours un typage fort !"; + // magic = 9; // ne fonctionnera pas car magic est désormais une chaîne de caractères + + // TYPES GÉNÉRIQUES + var agenda = new Dictionary<string, string>() { + {"Sarah", "212 555 5555"} // Ajout d'une entrée à notre agenda + }; + + // Appel de la fonction SetDefault (définie plus haut) + Console.WriteLine(SetDefault<string,string>(agenda, "Shaun", "Pas de numéro")); // => Pas de numéro + // Notez que vous n'avez pas à spécifier TKey et TValue car le compilateur saura les inférer. + Console.WriteLine(SetDefault(agenda, "Sarah", "No Phone")); // => 212 555 5555 + + // EXPRESSION LAMBDA - permet d'écrire une fonction en tant qu'expression + Func<int, int> square = (x) => x * x; // La dernière expression est la valeur de retour + Console.WriteLine(square(3)); // => 9 + + // GESTION AUTOMATIQUE DES RESSOURCES - vous permet de manipuler facilement des resources non-managées + // La plus part des objets qui accèdent à des ressources non-managées (handle de fichier, périphérique, etc.) + // implémentent l'interface IDisposable. L'instruction using prend soin + // de libérer les objets IDisposable proprement à votre place. + using (StreamWriter writer = new StreamWriter("log.txt")) + { + writer.WriteLine("Rien à signaler"); + // À la fin de cette portée les ressources seront libérées. + // Même si une exception est levée. + } + + // BIBLIOTHÈQUE DE TÂCHES PARALLÈLES (TPL) + // http://msdn.microsoft.com/fr-fr/library/dd460717.aspx + var websites = new string[] { + "http://www.google.com", "http://www.reddit.com", + "http://www.shaunmccarthy.com" + }; + var responses = new Dictionary<string, string>(); + + // L'exemple suivant exécutera chaque requête dans un thread séparé, + // et attendra la fin de chacun d'entre eux avant de continuer + Parallel.ForEach(websites, + new ParallelOptions() {MaxDegreeOfParallelism = 3}, // maximum de 3 threads + website => + { + // Fait quelque chose de long + using (var r = WebRequest.Create(new Uri(website)).GetResponse()) + { + responses[website] = r.ContentType; + } + }); + + // Ceci ne s'exécutera pas tant que les threads n'auront pas fini leur travail + foreach (var key in responses.Keys) + Console.WriteLine("{0}:{1}", key, responses[key]); + + // TYPE DYNAMIQUE - idéal pour travailler avec d'autres langages + dynamic student = new ExpandoObject(); + student.FirstName = "Mon prénom"; // Pas besoin de définir l'objet + + // Vous pouvez même ajouter des méthodes (dans cet exemple : la méthode prend une chaîne de caractères et retourne une chaîne de caractères) + student.Introduce = new Func<string, string>( + (introduceTo) => string.Format("Hey {0}, c'est {1}", student.FirstName, introduceTo)); + Console.WriteLine(student.Introduce("Beth")); + + // IQUERYABLE<T> - quasiment toutes les collections implémentent cette interface + // ce qui permet d'utiliser des méthodes de style 'Filter' / 'Map' / 'Reduce' + var bikes = new List<Bicycle>(); + bikes.Sort(); // Trie le tableau sur place + bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Trie en se basant sur la propriété Wheels + var result = bikes + .Where(b => b.Wheels > 3) // 'Filter' - enchaînable (retourne un IQueryable du type précédent) + .Where(b => b.IsBroken && b.HasTassles) + .Select(b => b.ToString()); // 'Map' - on retourne le .ToString() de chaque élément filtré, + // le résultat est un IQueryable<string> + + var sum = bikes.Sum(b => b.Wheels); // 'Reduce' - fait la somme de tous les Wheels de la liste + + // Creation d'une liste d'objet anonymes basés sur des paramètres de la classe Bike + var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles }); + // Le compilateur peut inférer le type de ces objets anonymes, permettant à certains IDE d'effectuer + // des autos-complétion. + foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome)) + Console.WriteLine(bikeSummary.Name); + + + // ASPARALLEL + // C'est ici que les choses se compliquent - un mélange de LINQ et de TPL + var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name); + // La ligne précédente s'exécute en parallèle ! Des threads seront gérés automatiquement + // et les données y seront réparties. Idéal sur de grosses données (et si votre + // machine dispose de plusieurs coeurs) + + + // LINQ - lie une source de données à des objets IQueryable<T> + // ex : LindToSql => liaison avec une base de données, LinqToXml => liaison avec un document xml + var db = new BikeRespository(); + + // l'exécution est décalée, ce qui est préférable quand on travaille sur une base données + var filter = db.Bikes.Where(b => b.HasTassles); // pas de requête exécutée + if (42 > 6) // Vous pouvez continuer à affiner la recherche + filter = filter.Where(b => b.IsBroken); // pas de requête exécutée + + var query = filter + .OrderBy(b => b.Wheels) + .ThenBy(b => b.Name) + .Select(b => b.Name); // toujours pas de requête exécutée + + // Maintenant la requête est exécutée, mais retourne des données uniquement au fil de l'itération + foreach (string bike in query) + Console.WriteLine(result); + + } + + } // Fin de la classe LearnCSharp + + // Il est possible d'inclure plusieurs classes dans un fichier .cs + + public static class Extensions + { + // EXTENSION DE FONCTIONS + public static void Print(this object obj) + { + Console.WriteLine(obj.ToString()); + } + } + + // Syntaxe de déclaration de classe : + // <public/private/protected/internal> class <class name>{ + // // champs, constructeurs, fonctions + // // tout est déclaré et implémenté à l'intérieur + // } + + public class Bicycle + { + // Propriétés et variable de la classe + public int Cadence // Public : peut être accédé de partout + { + get // get - définit une méthode pour lire la propriété + { + return _cadence; + } + set // set - définit une méthode pour affecter une valeur à la propriété + { + _cadence = value; // 'value' est la valeur passée en argument au setteur + } + } + private int _cadence; + + protected virtual int Gear // Protected : accessible depuis la classe et ses classes filles + { + get; // crée une propriété automatique, pas besoin de créer une variable de stockage + set; + } + + internal int Wheels // Internal : accessible depuis l'assembly + { + get; + private set; // Il est possible de choisir la portée d'un accesseur + } + + int _speed; // Par défaut tout est privé au sein d'une classe : accessible uniquement depuis la classe + // on peut ajouter explicitement le mot clé 'private' + + public string Name { get; set; } + + + // Enum est un type valeur formé par un ensemble de constantes nommées + // C'est simplement une manière de mettre un nom sur une valeur (int par défaut). + // Les types compatibles pour un enum sont : byte, sbyte, short, ushort, int, uint, long et ulong. + // Un enum ne peut pas contenir deux fois la même valeur + public enum BikeBrand + { + AIST, + BMC, + Electra = 42, // il est possible de donner explicitement une valeur + Gitane // 43 + } + // Nous avons défini cet enum à l'intérieur de la classe Bicycle, c'est donc un type imbriqué + // Pour le référencer à l'extérieur, il faudra utiliser Bicycle.BikeBrand + + public BikeBrand Brand; // Après avoir déclaré notre type enum, on peut créer un champ de ce type + + // Les membres statiques appartiennent à une classe plutôt qu'à une instance particulière + // Il est possible d'y accéder sans passer par un objet : + // ex : Console.WriteLine("Bicycles créés : " + Bicycle.bicyclesCreated); + static public int BicyclesCreated = 0; + + // Les valeurs en lecture seule sont affectées lors de l'exécution + // Elles ne peuvent être assignées que lors de leur déclaration ou dans un constructeur + readonly bool _hasCardsInSpokes = false; // variable en lecture et privée + + // Les constructeurs sont un moyen de créer des objets + // Voici un constructeur par défaut (pas d'arguments) + public Bicycle() + { + this.Gear = 1; // accès aux membres de la classe via le mot clé this + Cadence = 50; // qui est souvent implicite + _speed = 5; + Name = "Bontrager"; + Brand = BikeBrand.AIST; + BicyclesCreated++; + } + + // Voici un constructeur spécifique (qui prend des arguments) + public Bicycle(int startCadence, int startSpeed, int startGear, + string name, bool hasCardsInSpokes, BikeBrand brand) + : base() // possibilité d'appeler le constructeur de la classe mère (ici Object) + { + Gear = startGear; + Cadence = startCadence; + _speed = startSpeed; + Name = name; + _hasCardsInSpokes = hasCardsInSpokes; + Brand = brand; + } + + // Les constructeurs peuvent s'enchaîner + public Bicycle(int startCadence, int startSpeed, BikeBrand brand) : + this(startCadence, startSpeed, 0, "big wheels", true, brand) + { + } + + // Syntaxe de méthode : + // <public/private/protected> <type de retour> <nom de methode>(<args>) + + // Les classes peuvent implémenter des accesseurs pour leurs champs + // ou implémenter des propriétés (c'est la méthode dominante en C#) + + // Les paramètres de méthodes peuvent avoir des valeurs par défaut + // Dans ce cas, la méthode peut être appelée sans arguments + public void SpeedUp(int increment = 1) + { + _speed += increment; + } + + public void SlowDown(int decrement = 1) + { + _speed -= decrement; + } + + // Les propriétés se chargent de lire/modifier des valeurs + // elles peuvent être en lecture(get), en écriture(set) ou les deux + private bool _hasTassles; // variable privée + public bool HasTassles // propriété publique + { + get { return _hasTassles; } + set { _hasTassles = value; } + } + + // Il est possible de définir une propriété automatique sur une ligne + // cette syntaxe créera une variable de stockage automatiquement. + // Il est possible de modifier l'accèsibilité des getter/setter pour limiter leur utilisation + public bool IsBroken { get; private set; } + + // La même chose sur plusieurs lignes + public int FrameSize + { + get; + // Notez que seule la classe Bicycle peut changer la valeur de FrameSize + private set; + } + + // Méthode qui affiche la valeur des champs de cet objet + public virtual string Info() + { + return "Gear: " + Gear + + " Cadence: " + Cadence + + " Speed: " + _speed + + " Name: " + Name + + " Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") + + "\n------------------------------\n" + ; + } + + // Les méthodes peuvent aussi être statiques. Utile pour les méthodes d'aide. + public static bool DidWeCreateEnoughBycles() + { + // À l'intérieur d'une méthode statique on ne peut que référencer des membres statiques ! + return BicyclesCreated > 9000; + } // Si votre classe n'a que des membres statiques, marquez la comme statique + + } // fin de la classe Bicycle + + // PennyFarthing est une classe dérivée de Bicycle + class PennyFarthing : Bicycle + { + // Appel au constructeur de la classe mère + public PennyFarthing(int startCadence, int startSpeed) : + base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra) + { + } + + protected override int Gear + { + get + { + return 0; + } + set + { + // Lève une exception + throw new ArgumentException("Impossible de modifier Gear sur un PennyFarthing"); + } + } + + public override string Info() + { + string result = "PennyFarthing bicycle "; + result += base.ToString(); // Appel à la version de base de cette méthode + return result; + } + } + + // Les interfaces contiennent uniquement la signature de leurs membres, sans implémentation. + interface IJumpable + { + void Jump(int meters); // Tous les membres d'interface sont publics par défaut + } + + interface IBreakable + { + bool Broken { get; } // Les interfaces peuvent contenir des propriétés, + // des méthodes et des évènements + } + + // Une classe ne peut hériter que d'une seule autre classe, mais peut implémenter plusieurs interfaces + class MountainBike : Bicycle, IJumpable, IBreakable + { + int damage = 0; + + public void Jump(int meters) + { + damage += meters; + } + + public bool Broken + { + get + { + return damage > 100; + } + } + } + + /// <summary> + /// Utilisé pour illustrer la connexion à une base donnée dans l'exemple LinqToSql + /// L'approche code first d'EntityFramework est très pratique (un peu comme ActiveRecord de Ruby) + /// http://msdn.microsoft.com/fr-fr/data/jj193542.aspx + /// </summary> + public class BikeRespository : DbSet + { + public BikeRespository() + : base() + { + } + + public DbSet<Bicycle> Bikes { get; set; } + } +} // Fin du namespace +``` + +## Sujets non-abordés + + * Flags + * Attribus + * Propriétés statiques + * Exceptions, Abstraction + * ASP.NET (Web Forms/MVC/WebMatrix) + * Winforms + * Windows Presentation Foundation (WPF) + +## Lectures Complémentaires + + * [DotNetPerls](http://www.dotnetperls.com) + * [C# in Depth](http://manning.com/skeet2) + * [Programming C#](http://shop.oreilly.com/product/0636920024064.do) + * [LINQ](http://shop.oreilly.com/product/9780596519254.do) + * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx) + * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials) + * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials) + * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials) + * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) + +[Convention de codage C#](http://msdn.microsoft.com/library/vstudio/ff926074) diff --git a/fr-fr/haskell.html.markdown b/fr-fr/haskell.html.markdown index 9d0cec99..989db1d5 100644 --- a/fr-fr/haskell.html.markdown +++ b/fr-fr/haskell.html.markdown @@ -5,6 +5,7 @@ contributors: translators: - ["David Baumgartner", "http://davidbaumgartner.ch"] lang: fr-fr +filename: learnhaskell-fr.hs --- Haskell a été conçu pour être un langage fonctionnel pur et maniable. Il est connu pour ses monades et son système de types, mais je n'ai cesse d'y revenir pour son élégance. Pour moi, Haskell fait de la programmation une joie. diff --git a/fr-fr/objective-c-fr.html.markdown b/fr-fr/objective-c-fr.html.markdown new file mode 100644 index 00000000..b98d161e --- /dev/null +++ b/fr-fr/objective-c-fr.html.markdown @@ -0,0 +1,528 @@ +--- + +language: Objective-C +contributors: + - ["Eugene Yagrushkin", "www.about.me/yagrushkin"] + - ["Yannick Loriot", "https://github.com/YannickL"] + - ["Levi Bostian", "https://github.com/levibostian"] +translators: + - ["Yannick Loriot", "https://github.com/YannickL"] +filename: LearnObjectiveC-fr.m +lang: fr-fr + +--- + +L'Objective-C est un langage de programmation orienté objet réflexif principalement utilisé par Apple pour les systèmes d'exploitations Mac OS X et iOS et leurs frameworks respectifs, Cocoa et Cocoa Touch. + +```cpp +// Les commentaires sur une seule ligne commencent par // + +/* +Les +commentaires +multi-lignes +ressemblent +à +ceci +*/ + +// #import permet d'importer les en-têtes d'autres fichiers +// Utilisez <> pour importer des fichiers globaux (en général des frameworks) +// Utilisez "" pour importer des fichiers locaux (du projet) +#import <Foundation/Foundation.h> +#import "MaClasse.h" + +// Si vous activez les modules dans les projets iOS >= 7 ou Mac OS X >= 10.9 +// dans Xcode 5, vous pouvez importer les frameworks comme cela : +@import Foundation; + +// Le point d'entrée de votre programme est une fonction qui s'appelle main +// et qui retourne un entier comme type +int main (int argc, const char * argv[]) +{ + // Créer un groupe de libération automatique de la mémoire pour l'ensemble + // du programme + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + // Si vous utilisez le comptage de référence automatique (ARC), utilisez + // @autoreleasepool à la place : + @autoreleasepool { + + // NSLog() permet d'afficher une chaine de caractères dans la console + // Affiche la chaine de caractères "Bonjour Tous Le Monde !" + NSLog(@"Bonjour tous le Monde !"); + + /////////////////////////////////////// + // Les Types & Les Variables + /////////////////////////////////////// + + // La déclaration de primitive + int maPrimitive1 = 1; + long maPrimitive2 = 234554664565; + + // La déclaration d'objet + // Il faut mettre un astérisque devant la déclaration d'objet fortement typé + MaClasse *monObject1 = nil; // Typage fort + id monObject2 = nil; // Typage faible + // 'description' est une méthode qui permet de retourner un aperçut de l'objet sous forme textuelle + // La méthode 'description' est appelée par défaut quand on utilise le paramètre '%@' + NSLog(@"%@ and %@", monObject1, [monObject2 description]); // Affiche "(null) et (null)" + + // Les chaines de caractères + NSString *chaineMonde = @"Monde"; + NSLog(@"Bonjour tous le %@ !", chaineMonde); // affiche => "Bonjour Tous Le Monde !" + // NSMutableString est une chaine mutable + NSMutableString *chaineMutable = [NSMutableString stringWithString:@"Bonjour tous le"]; + [chaineMutable appendString:@" Monde !"]; + NSLog(@"%@", chaineMutable); // affiche => "Bonjour Tous Le Monde !" + + // Les caractères + NSNumber *laLettreZSousFormeDeNombre = @'Z'; + char laLettreZ = [laLettreZSousFormeDeNombre charValue]; // ou 'Z' + NSLog(@"%c", laLettreZ); + + // Les nombres + NSNumber *nombreQuaranteDeux = @42; + int quaranteDeux = [nombreQuaranteDeux intValue]; // ou 42 + NSLog(@"%i", quaranteDeux); + + NSNumber *nombreQuaranteDeuxnonSigne = @42U; + unsigned int quaranteDeuxnonSigne = [nombreQuaranteDeuxnonSigne unsignedIntValue]; + NSLog(@"%u", fortyTwoUnsigned); + + NSNumber *nombreQuaranteDeuxCourt = [NSNumber numberWithShort:42]; + short quaranteDeuxCourt = [nombreQuaranteDeuxCourt shortValue]; // ou 42 + NSLog(@"%hi", fortyTwoShort); + + NSNumber *nombreQuaranteDeuxLong = @42L; + long quaranteDeuxLong = [nombreQuaranteDeuxLong longValue]; // ou 42 + NSLog(@"%li", fortyTwoLong); + + // Les nombres flottants + NSNumber *nombrePiFlottant = @3.141592654F; + float piFlottant = [nombrePiFlottant floatValue]; // ou 3.141592654f + NSLog(@"%f", piFlottant); // affiche => 3.141592654 + NSLog(@"%5.2f", piFlottant); // affiche => " 3.14" + + NSNumber *nombrePiDouble = @3.1415926535; + double piDouble = [nombrePiDouble doubleValue]; // ou 3.1415926535 + NSLog(@"%f", piDouble); + NSLog(@"%4.2f", piDouble); // affiche => "3.14" + + // NSDecimalNumber est une classe pour avoir plus de précision sur les nombres + // flottants et les doubles + NSDecimalNumber *decNumUn = [NSDecimalNumber decimalNumberWithString:@"10.99"]; + NSDecimalNumber *decNumDeux = [NSDecimalNumber decimalNumberWithString:@"5.002"]; + // NSDecimalNumber ne permet pas d'utiliser les opérations standards (+, -, *, /) + // Il faut utiliser les méthodes suivantes à la place : + [decNumUn decimalNumberByAdding:decNumDeux]; + [decNumUn decimalNumberBySubtracting:decNumDeux]; + [decNumUn decimalNumberByMultiplyingBy:decNumDeux]; + [decNumUn decimalNumberByDividingBy:decNumDeux]; + NSLog(@"%@", decNumUn); // affiche => 10.99 comme NSDecimalNumber est immuable + + // Les booléens + NSNumber *ouiNumber = @YES; + NSNumber *nonNumber = @NO; + // ou + BOOL ouiBool = YES; + BOOL nonBool = NO; + NSLog(@"%i", ouiBool); // affiche => 1 + + // Les listes + // Une liste peut contenir uniquement des objets + NSArray *uneListe = @[@1, @2, @3, @4]; + NSNumber *troisiemeNombre = uneListe[2]; + NSLog(@"Troisième nombre = %@", troisiemeNombre); // affiche "Troisième nombre = 3" + // NSMutableArray est une version mutable de NSArray + // Cela permet de modifier la liste en ajoutant de nouveaux éléments et en supprimant ou + // changeant de place des objets déjà présent + // C'est très pratique, mais pas aussi performant que l'utilisation de la classe NSArray + NSMutableArray *listeMutable = [NSMutableArray arrayWithCapacity:2]; + [listeMutable addObject:@"Bonjour tous le"]; + [listeMutable addObject:@"Monde"]; + [listeMutable removeObjectAtIndex:0]; + NSLog(@"%@", [listeMutable objectAtIndex:0]); // affiche => "Monde" + + // Les dictionnaires + // Un dictionnaire est un ensemble de clés : valeurs + NSDictionary *unDictionnaire = @{ @"cle1" : @"valeur1", @"cle2" : @"valeur2" }; + NSObject *valeur = unDictionnaire[@"Une clé"]; + NSLog(@"Objet = %@", valeur); // affiche "Objet = (null)" + // NSMutableDictionary est un dictionnaire mutable, c-à-d que l'on peut modifier + NSMutableDictionary *dictionnaireMutable = [NSMutableDictionary dictionaryWithCapacity:2]; + [dictionnaireMutable setObject:@"valeur1" forKey:@"cle1"]; + [dictionnaireMutable setObject:@"valeur2" forKey:@"cle2"]; + [dictionnaireMutable removeObjectForKey:@"cle1"]; + + // Les ensembles + // Un ensemble ne peut contenir de duplicatas contrairement aux NSArray + NSSet *ensemble = [NSSet setWithObjects:@"Salut", @"Salut", @"Monde", nil]; + NSLog(@"%@", ensemble); // affiche => {(Salut, Monde)} (Pas forcément dans le même ordre) + // NSMutableSet est un ensemble mutable + NSMutableSet *ensembleMutable = [NSMutableSet setWithCapacity:2]; + [ensembleMutable addObject:@"Salut"]; + [ensembleMutable addObject:@"Salut"]; + NSLog(@"%@", ensembleMutable); // affiche => {(Salut)} + + /////////////////////////////////////// + // Les Operateurs + /////////////////////////////////////// + + // Les opérateurs sont pareil qu'en C + // Par exemple : + 2 + 5; // => 7 + 4.2f + 5.1f; // => 9.3f + 3 == 2; // => 0 (NO) + 3 != 2; // => 1 (YES) + 1 && 1; // => 1 (et logique) + 0 || 1; // => 1 (ou logique) + ~0x0F; // => 0xF0 (négation bit à bit) + 0x0F & 0xF0; // => 0x00 (et bit à bit) + 0x01 << 1; // => 0x02 (décalage à gauche (par 1)) + + /////////////////////////////////////// + // Les Structures de Contrôle + /////////////////////////////////////// + + // Structure "Si-Sinon" (If-Else) + if (NO) + { + NSLog(@"Je ne suis jamais affiché"); + } else if (0) + { + NSLog(@"Je ne suis jamais affiché aussi"); + } else + { + NSLog(@"Je suis affiché"); + } + + // Structure "Selon" (Switch) + switch (2) + { + case 0: + { + NSLog(@"Je ne suis jamais affiché"); + } break; + case 1: + { + NSLog(@"Je ne suis jamais affiché aussi"); + } break; + default: + { + NSLog(@"Je suis affiché"); + } break; + } + + // Structure de boucle "Tant Que" (While) + int ii = 0; + while (ii < 4) + { + NSLog(@"%d,", ii++); // ii++ incrémente ii après avoir utilisé sa valeur + } // => affiche "0," + // "1," + // "2," + // "3," + + // Structure de boucle "Pour" (For) + int jj; + for (jj=0; jj < 4; jj++) + { + NSLog(@"%d,", jj); + } // => affiche "0," + // "1," + // "2," + // "3," + + // Structure de boucle "Pour Chaque" (Foreach) + NSArray *valeurs = @[@0, @1, @2, @3]; + for (NSNumber *valeur in valeurs) + { + NSLog(@"%@,", valeur); + } // => affiche "0," + // "1," + // "2," + // "3," + + // Structure "Essayer-Attraper-Finalement" (Try-Catch-Finally) + @try + { + @throw [NSException exceptionWithName:@"FileNotFoundException" + reason:@"Fichier non trouvé" userInfo:nil]; + } @catch (NSException * e) + { + NSLog(@"Une exception est survenue : %@", e); + } @finally + { + NSLog(@"Finalement"); + } // => affiche "Une exception est survenue : Fichier non trouvé" + // "Finalement" + + /////////////////////////////////////// + // Les Objets + /////////////////////////////////////// + + // Définis et créé une instance d'objet en allouant un espace mémoire puis en + // l'initialisant. Un objet n'est pas complétement fonctionnel tant que les deux + // étapes précédentes ne sont pas terminées + MaClass *monObjet = [[MaClass alloc] init]; + + // L'Objet en Objective-C est basé sur le principe d'envoie de message et non sur + // celui d'appel de méthode comme la plupart des autres langages + // C'est un détail important car cela veut dire que l'on peut envoyer un message + // à un objet qui ne possède pas la méthode demandée sans aucune incidence sur le + // fonctionnement du programme (aucune exception ne sera levée) + [myObject instanceMethodWithParameter:@"Steve Jobs"]; + + // Nettoie la mémoire qui a été utilisée dans le programme + [pool drain]; + + // Fin de l'@autoreleasepool + } + + // Fin du programme + return 0; +} + +/////////////////////////////////////// +// Les Classes et Les Fonctions +/////////////////////////////////////// + +// Déclaration d'une classe dans un en-tête de fichier (MaClasse.h) : +// La déclaration d'une classe en Objective-C commence par la déclaration de son interface : +// @interface NomDeLaClasse : NomDeLaClasseParent <ListeDesProtocoles> +// { +// type nom; // Déclaration d'une variable; +// } +// @property type nom; // Déclaration d'une propriété +// -/+ (type)nomDeLaMethode; // Déclaration d'une methode +// @end // Termine la déclaration +// NSObject est la classe de base (super classe) en Objective-C +@interface MaClasse : NSObject <MonProtocole> +{ + int nombre; // Accès protégé par défaut (équivalent à '@protected int nombre;') + @private id donnee; // Accès privé (il est plus pratique de le faire dans l'implémentation) + NSString *nom; +} +// Les propriétés permettent de générer les accésseurs/affecteurs publiques à la compilation +// Par défaut, le nom de l'affecteur est la chaine 'set' suivi par le nom de la @property +@property int propInt; // Nom de l'affecteur = 'setPropInt' +@property (copy) id copyId; // (copy) => Copie l'objet pendant l'affectation +// (readonly) => Ne peut pas affecté la variable en dehors de l'@interface +// Il faut utiliser le mot clé '@synthesize' dans l'@implementation pour créer l'accésseur +@property (readonly) NSString *roString; +// Vous pouvez aussi personnaliser les noms des accésseurs ou des affecteurs +@property (getter=longeurGet, setter=longeurSet:) int longeur; + +// Methodes ++/- (TypeDeRetour)signatureDeLaMethode:(TypeDuParametre *)nomDuParametre; + +// '+' signifie que c'est une méthode de classe (statique) : ++ (NSString *)methodeDeClasse; ++ (MaClasse *)maClasseDepuisLaHauteur:(NSNumber *)hauteurParDefaut; + +// '-' pour les méthodes d'instances : +- (NSString *)methodeInstanceAvecUnParametre:(NSString *)string; +- (NSNumber *)methodeInstanceAvecUnParametre:(NSString*)string puisUnDeuxieme:(NSNumber *)number; + +// Contructeur avec des arguments : +- (id)initAvecDistance:(int)distanceParDefault; +// Les méthodes en Objective-C sont très descriptives + +@end // Fin de l'interface + + +// Voici un exemple d'utilisation de MaClasse +MaClasse *maClasse = [[MaClasse alloc] init]; // créer une instance de MaClasse +[maClasse setNombre:10]; +NSLog(@"%d", [maClasse nombre]); // affiche => 10 +[myClass longeurSet:32]; +NSLog(@"%i", [maClasse longeurGet]); // affiche => 32 +// Pour des raisons pratiques vous pouvez aussi utiliser la notation en point pour accéder aux +// variables d'instances : +maClasse.nombre = 45; +NSLog(@"%i", maClasse.nombre); // maClasse => 45 + +// Pour appeler une méthode de classe : +NSString *s1 = [MaClasse methodeDeClasse]; +MaClasse *m2 = [MaClasse maClasseDepuisLaHauteur:38]; + +// Pour appeler une méthode d'instance : +MaClasse *maClasse = [[MaClasse alloc] init]; // Créer une instance de MaClasse +NSString *stringDepuisUneInstanceDeMethode = [maClasse methodeInstanceAvecUnParametre:@"Salut"]; + +// Les sélecteurs sont un moyen de décrire les méthodes dynamiquement +// Ils sont utilisés pour appeler des méthodes de classe et avoir des pointeurs de fonctions +// facilement manipulable +// SEL est un type de donnée et @selector retourne un selecteur à partir d'un nom de methode +SEL selecteur = @selector(methodeInstanceAvecUnParametre:puisUnDeuxieme:); +if ([maClasse respondsToSelector:selecteur]) { // Vérifie si la classe possède la méthode + // Met les arguments de la méthode dans un seul objet pour l'envoyer via la fonction + // performSelector:withObject: + NSArray *arguments = [NSArray arrayWithObjects:@"Hello", @4, nil]; + [myClass performSelector:selectorVar withObject:arguments]; // Appele la méthode via le sélecteur +} +else { + // NSStringFromSelector() retourne une chaine de caractères à partir d'un sélecteur + NSLog(@"MaClasse ne possède pas de méthode : %@", NSStringFromSelector(selecteur)); +} + +// Le fichier d'implémentation de la classe MaClasse (MaClasse.m) doit commencer comme ceci : +@implementation MaClasse { + long distance; // Variable d'instance privée (équivalent à @private dans l'interface) + NSNumber hauteur; +} + +// Pour accéder à une variable depuis l'implémentation on peut utiliser le _ (tiret bas) devant le nom +// de la variable : +_nombre = 5; +// Accès d'une variable définie dans le fichier d'implémentation : +distance = 18; +// Pour utiliser la variable définie par l'intermédiaire de @property, il faut utiliser @synthesize +// qui permet de créer les affecteurs et les accésseurs correspondants : +@synthesize roString = _roString; // _roString est maintenant disponible dans l'implementation + +// A l'inverse dela méthode 'init' qui est appelée lors de la création d'un objet, la fonction +// 'dealloc' est appelée quand l'objet est supprimé +- (void)dealloc +{ + [hauteur release]; // Si vous n'utilisez pas ARC, pensez bien à supprimer l'objet + [super dealloc]; // et à appeler la méthode 'dealloc' de la classe parent +} + +// Les constructeurs sont des fonctions qui permettent d'instancier un objet +// 'init' est le constructeur par défaut en Objective-C +- (id)init +{ + if ((self = [super init])) // 'super' est utilisé pour appeler la méthode de la classe parent + { + self.count = 1; // 'self' permet d'appeler la méthode de l'instance courante + } + return self; +} + +// Vous pouvez aussi créer des constructeurs avec des arguments +// Attention : chaque nom de constructeur doit absolument commencer par 'init' +- (id)initAvecUneDistance:(int)distanceParDefault +{ + if ((self = [super init])) + { + distance = distanceParDefault; + return self; + } +} + +// Implémentation d'une méthode de classe ++ (NSString *)methodDeClasse +{ + return [[self alloc] init]; +} + ++ (MaClasse *)maClasseDepuisUneHauteur:(NSNumber *)hauteurParDefaut +{ + hauteur = hauteurParDefaut; + return [[self alloc] init]; +} + +// Implémentation d'une méthode d'instance +- (NSString *)methodeInstanceAvecUnParametre:(NSString *)string +{ + return @"Ma chaine de caractère"; +} + +- (NSNumber *)methodeInstanceAvecUnParametre:(NSString*)string puisUnDeuxieme:(NSNumber *)number +{ + return @42; +} + +// Pour créer une méthode privée, il faut la définir dans l'implementation et non pas dans +// l'interface +- (NSNumber *)methodePrivee +{ + return @72; +} + +[self methodePrivee]; // Appel de la méthode privée + +// Implémentation d'une méthode qui est déclarée dans <MonProtocole> +- (void)methodeDuProtocole +{ + // expressions +} + +@end // Fin de l'implémentation + +/* + * Un protocole déclare des méthodes et propriétés que chaque implémentation doit avoir afin de se + * conformer à celui-ci + * Un protocole n'est pas une classe, c'est juste une interface + */ +@protocol MonProtocole + - (void)methodeDuProtocole; +@end + + +/////////////////////////////////////// +// Gestion de la mémoire +/////////////////////////////////////// +/* +À chaque fois qu'un objet est créé dans l'application, un bloc mémoire doit être alloué. +Quand l'application en a fini avec cet objet, la mémoire doit être libérée afin d'éviter les fuites +mémoires +Il n'y a pas de ramasse-miettes en Objective-C contrairement à Java par exemple. La gestion de la +mémoire repose sur le comptage de référence qui, pour chaque objet, assigne un compteur qui permet +de connaitre le nombre de référence qui l'utilise. + +Le principe est le suivant : +Lorsque l'objet est créé, le compteur est initialisé à 1. Quand une instance détient un objet, le +compteur est incrémenté de un. Quand l'objet est libéré, le compteur est décrémenté de un. Au moment +où le compteur arrive à zéro, l'objet est supprimé de la mémoire + +Une bonne pratique à suivre quand on travaille avec des objets est la suivante : +(1) créer un objet, (2) utiliser l'objet, (3) supprimer l'objet de la mémoire +*/ + +MaClasse *classeVar = [MyClass alloc]; // 'alloc' incrémente le compteur de référence +[classeVar release]; // Décrémente le compteur de rérence +// 'retain' incrémente le compteur de référence +// Si 'classeVar' est libéré, l'objet reste en mémoire car le compteur de référence est non nul +MaClasse *nouvelleVar = [classVar retain]; +[classeVar autorelease]; // Supprime l'appartenance de l'objet à la fin du bloc + +// Les @property peuvent utiliser 'retain' et 'assign' +@property (retain) MaClasse *instance; // Libère l'ancienne valeur et retient la nouvelle +@property (assign) NSSet *set; // Pointeur vers la valeur sans retenir/libérer l'ancienne valeur + +// Automatic Reference Counting (ARC) +// La gestion de la mémoire étant pénible, depuis iOS 4 et Xcode 4.2, Apple a introduit le comptage de +// référence automatique (Automatic Reference Counting en anglais) +// ARC est une fonctionnalité du compilateur qui permet d'ajouter les 'retain', 'release' et 'autorelease' +// automatiquement. Cela veut dire que lorsque vous utilisez ARC vous ne devez plus utiliser ces mot-clés +MaClasse *arcMaClasse = [[MaClasse alloc] init]; +// ... code utilisant arcMaClasse +// Sans ARC, vous auriez dû appeler [arcMaClasse release] après avoir utilisé l'objet. Mais avec ARC +// activé il n'est plus nécessaire de le faire car le compilateur ajoutera l'expréssion automatiquement +// pour vous + +// Les mots clés 'assign' et 'retain', avec ARC sont respectivement remplacé par 'weak' et 'strong' +@property (weak) MaClasse *weakVar; // 'weak' ne retient pas l'objet. Si le compteur de référence +// descend à zero, weakVar sera automatiquement mis à nil +@property (strong) MaClasse *strongVar; // 'strong' prend possession de l'objet comme le ferait avec +// le mot-clé 'retain' + +// Pour l'instanciation des variables (en dehors de @property), vous pouvez utiliser les instructions +// suivantes : +__strong NSString *strongString; // Par défaut. La variable est retenue en mémoire jusqu'à la fin +// de sa portée +__weak NSSet *weakSet; // Maintient une référence vers l'objet sans incrémenter son compteur de référence : +// Lorsque l'objet sera supprimé, weakSet sera mis à nil automatiquement +__unsafe_unretained NSArray *unsafeArray; // Comme __weak, mais la variable n'est pas mis à nil quand +// l'objet est supprimé + +``` +## Lectures Complémentaires + +[La Page Wikipedia de l'Objective-C](http://fr.wikipedia.org/wiki/Objective-C) + +[iOS pour les écoliers : Votre première app iOS](http://www.raywenderlich.com/fr/39272/ios-pour-les-ecoliers-votre-premiere-app-ios-partie-12) + +[Programming with Objective-C. Apple PDF book](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/ProgrammingWithObjectiveC.pdf) diff --git a/fr-fr/python-fr.html.markdown b/fr-fr/python-fr.html.markdown index 9dbdafe1..58a036ba 100644 --- a/fr-fr/python-fr.html.markdown +++ b/fr-fr/python-fr.html.markdown @@ -75,7 +75,7 @@ not False #=> True # Les chaînes de caractères sont créées avec " ou ' "C'est une chaîne." -'C'est aussi une chaîne.' +'C\'est aussi une chaîne.' # On peut aussi les "additioner" ! "Hello " + "world!" #=> "Hello world!" |