Quelle est la logique derrière avoir une version mutable et immuable de classs comme NSArray, NSDictionary etc dans Objective C?

Pourquoi les classs de collection communes dans Objective C comme NSSsortingng, NSArray, NSDictionary etc ont une version mutable ainsi qu'une version immuable. Quelle est la logique derrière les définir séparément? Performance, memory management ou autre chose?

    Les versions immuables des classs existent parce qu'un object immuable est, en soi, un identifiant unique pour un état particulier . C'est-à-dire que si vous avez un NSArray de 100 instances NSSsortingng , cette instance NSArray peut être traitée comme idempotente pour l'une de ces strings.

    De même, l'immutabilité signifie qu'un changement ne peut pas se produire après que l'état a été vendu. Par exemple, la NSView des sous- NSView de subviews renvoie un tableau immuable, garantissant ainsi que l'appelant ne va pas jouer à des jeux avec le contenu (ni même s'attendre à pouvoir le faire). En interne, NSView peut choisir de renvoyer le NSMutableArray [probable] qui contient les sous-vues (puisqu'il est modifiable en interne) et le transtypage de NSArray signifie que l'appelant ne peut pas manipuler le contenu sans un avertissement de maléfice ou de mauvais compilateur. (Ceci peut ou peut ne pas être réellement l'implémentation réelle, btw – mais ce model est utilisé ailleurs).

    L'immutabilité signifie également que le dénombrement et / ou la traversée peuvent être effectués sans risque de changement d'état au milieu. De même, de nombreuses classs immuables sont également explicitement sécurisées. n'importe quel nombre de threads peut simultanément lire l'état immuable, souvent sans avoir besoin d'un verrou.

    En général pour une API, une class immuable va être thread-safe pour que vous puissiez la lire directement dans un thread d'arrière-plan sans vous soucier du contenu qui va changer …

    Cela count davantage pour des choses comme une collection où le contenu peut changer et vous pourriez être au milieu de les énumérer.

    Pourquoi les classs de collection communes dans Objective C comme NSSsortingng, NSArray, NSDictionary etc ont une version mutable ainsi qu'une version immuable.

    le concept est utilisé dans les langages connexes. la distinction notable est que les types d'objc sont nommés variants mutables. Les langauges similaires accomplissent typiquement ceci par l'application d'un mot-key, tel que const . bien sûr, d'autres langages apparentés utilisent aussi des types qui sont explicitement mutables ou immuables.

    Quelle est la logique derrière les définir séparément?

    La messagerie objc ne distingue pas const et non-const, et le langage ne fournit pas de support embedded pour s'assurer que l'état d'un object ne change pas (bien que cela ne soit pas vraiment compliqué si l'on est vraiment enclin à étendre un compilateur). donc il y a un peu d'histoire impliqué ici aussi.

    par conséquent, c'est une convention pour la class de définir l'immuabilité par rapport à la mutabilité, et de fournir des variantes qui distinguent la mutabilité.

    Les abstractions multiples introduisent également le type de security et d'intention.

    Performance

    Oui. il y a plusieurs optimizations qu'un object invariant peut faire.

    certains cas include:

    • il pourrait cacher des valeurs, ne jamais les calculer plus d'une fois.
    • il pourrait utiliser des allocations exactes, non résiliables pour ses données.
    • il n'a souvent pas besoin de code spécial pour une utilisation multithread – de nombreux types immuables ne feront que muter pendant la construction / destruction.
    • ces types utilisent souvent des clusters de class. Si un cluster de class est implémenté, alors les implémentations spécialisées peuvent fournir des différences significatives dans la memory, l'implémentation, etc. Considérez comment une string immuable avec exactement un caractère peut différer d'une variante mutable.

    memory management

    certains cas include:

    • Les types immuables pourraient partager leur contenu immuable.
    • ils peuvent également réduire les allocations. par exemple, une implémentation de copyWithZone: ou initWithType: pourrait renvoyer la source conservée, plutôt qu'une copy physique de profondeur ou superficielle.

    ou autre chose?

    il est plus facile d'écrire des interfaces claires. vous pouvez garantir et (tenter de) restreindre certaines choses. si tout était mutable, il y aurait beaucoup plus d'erreurs à faire et des cas spéciaux. en fait, la distinction pourrait changer complètement la façon dont nous abordons l'écriture des bibliothèques d'objc:

     [[textField ssortingngValue] appendSsortingng:@" Hz"]; [textField stateDidChange]; 

    il est donc agréable de pouvoir faire circuler des objects sans craindre que le client ne change dans votre dos, tout en évitant de les copyr partout.

    Fondamentalement, quand vous savez qu'une structure de données est immuable, vous pouvez faire beaucoup d'optimizations autour de cela. Par exemple, si un tableau est immuable, vous pouvez omettre tout le code qui "développera" le tableau chaque fois que vous tenterez d'append un object, et vous pouvez simplement avoir votre tableau immuable comme un wrapper autour d'un id[] .

    Outre les réponses mentionnées ci-dessus, une différence est la suivante: Les objects immuables sont généralement sans danger pour le fil. Considérant que, les objects Mutable ne sont pas thread-safe.

    Merci