web-dev-qa-db-fra.com

quelle est la différence entre alloc et allocWithZone:?

D'après discussion sur le forum , il semble que la grande différence soit le facteur de performance, allocWithZone: allouera de la mémoire à partir d'une zone de mémoire particulière, ce qui réduira le coût de l'échange. 

En pratique, pratiquement aucune chance d'utiliser allocWithZone:, n'importe qui peut donner un exemple simple pour illustrer le cas d'utilisation de allocWithZone:? 

Merci,

50
Forrest

Lorsqu'un objet en crée un autre, c'est parfois une bonne idée de s’assurer que ils sont tous deux affectés du même région de mémoire. La méthode de la zone (déclaré dans le protocole NSObject) peut être utilisé à cette fin; il renvoie la zone où se trouve le récepteur situé.

Cela me suggère que vos ivars et tous les objets que vos classes "créent" eux-mêmes pourraient utiliser +allocWithZone: de cette manière pour créer les instances qu'ils créent dans la même zone.

-(id)init {
  if (self = [super init]) {
    someIvar = [[SomeOtherClass allocWithZone:[self zone]] init];
  }

  return self;
}
47
d11wtq

De la documentation d'Apple:

Cette méthode existe pour des raisons historiques; les zones de mémoire ne sont plus utilisé par Objective-C.

30
Rivera

Un bon exemple d'utilisation de allocWithZone: est la mise en œuvre du protocole NSCopy, qui vous permet de rendre vos objets personnalisés copiables (copie complète/copie par valeur) comme: 

(1) ClassName *newObject = [currentObject copy]; //results in newObject being a copy of currentObject not just a reference to it

Le protocole NSCopy vous assure de mettre en œuvre une méthode:

(2) -(id)copyWithZone:(NSZone *)zone;

Lors de la copie d'un objet, le message "copie" que vous envoyez comme indiqué ci-dessus (1) lorsque "copyWithZone" envoie un message à la méthode (2). Autrement dit, vous n'avez rien à faire pour obtenir une zone vous-même.

Maintenant que vous avez une "zone" envoyée à ce message, vous pouvez l'utiliser pour vous assurer qu'une copie est faite à partir de la mémoire dans la même région que l'original.

Cela peut être utilisé comme:

-(id)copyWithZone:(NSZone *)zone
{
   newCopy = [[[self class]allocWithZone:zone]init]; //gets the class of this object then allocates a new object close to this one and initialises it before returning
   return(newCopy);
}

C’est le seul endroit où, à ma connaissance, allocWithZone est réellement utilisé.

5
Richard Washington

J'utilise allocWithZone en singleton. Comme Forrest l'a mentionné, les variables créées sont allouées à partir de la même région de mémoire. Ainsi, d’autres classes peuvent les utiliser ou y accéder à partir de la même zone de mémoire. Économisez de l'espace mémoire lorsque vous exécutez votre application.

2
felixwcf

Dans le Référence sur les fonctions de base , toutes les fonctions Zone sont maintenant précédées du message ci-dessous qui avertit que les zones seront ignorées.

Les zones sont ignorées sous iOS et le runtime 64 bits sous OS X. Vous ne devez pas utiliser de zones dans le développement en cours.

NSCreateZone
NSRecycleZone
NSSetZoneName
NSZoneCalloc
NSZoneFree
NSZoneFromPointer
NSZoneMalloc
NSZoneName
NSZoneRealloc
NSDefaultMallocZone
2
pkamb

Même si la documentation de Apple indique que allocWithZone: 

existe pour des raisons historiques; Les zones de mémoire ne sont plus utilisées par Objective-C. Vous ne devez pas remplacer cette méthode.

et

Les zones sont ignorées sous iOS et le runtime 64 bits sous OS X. Vous ne devez pas utiliser de zones dans le développement en cours.

en réalité, je l'ai remplacée dans une classe Objective-C (dans un projet Objective-C complet) et la méthode est appelée lorsque je sais [[Mylass alloc] init] même si la construction est exécutée sur un iPhone 6.

Mais je pense qu'il vaut mieux suivre la documentation et surcharger la méthode alloc au lieu de celle-ci car alloc peut certainement faire le même travail.

0
Thibault