2010-12-23 19 views
48

De forum discussion, parece que la gran diferencia es el factor de rendimiento, allocWithZone: alocará memoria desde un área de memoria particular, lo que reducirá el costo de intercambio.¿cuál es la diferencia entre alloc y allocWithZone :?

En la práctica, casi no tiene oportunidad de usar allocWithZone:, cualquiera puede dar un ejemplo simple para ilustrar qué caso usar allocWithZone:?

Gracias,

+7

Tenga en cuenta que la documentación de Apple actual (2014) dice que el parámetro 'zone' se ignora, y que" Este método existe por razones históricas, Objective-C ya no usa las zonas de memoria. " Entonces la respuesta aceptada puede no ser la correcta. –

Respuesta

45

Cuando un objeto crea otro, es veces una buena idea para asegurarse de los dos están asignados a la misma región de la memoria. El método de zona (declarado en el protocolo NSObject) se puede usar para este propósito; devuelve la zona donde se encuentra el receptor .

Esto me sugiere que sus Ivars, y cualquier objeto de sus clases de "crear" a sí mismos podrían hacer uso de +allocWithZone: de esta manera, hacer que los casos que crean en la misma zona.

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

    return self; 
} 
+0

Sí, ese es un buen ejemplo para usar allocWithZone: – Forrest

+44

Correcto. La realidad, sin embargo, es que prácticamente nada usa zonas. Originalmente, se pensó para dar la capacidad de, por ejemplo, ubicar conjuntamente todos los objetos relacionados con un documento en una zona y luego destruirlos en masa simplemente desasignando la zona. En la práctica, esto resultó inviable y las zonas no se han utilizado en más de una década en las API de OpenStep. – bbum

+0

Gracias por eso. Muy informativo. Pensé que dada la falta de concentración en ellos en la documentación, no se usan mucho. – d11wtq

5

Un buen ejemplo para el uso de allocWithZone: es cuando se va a implementar el protocolo NSCopy, que le permite realizar su encargo objetos copiable (copia profunda/copia de valor) como:

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

El NSCopy protocolo garantiza que implemente un método:

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

al copiar un objeto del mensaje de 'copia' que envía el anterior (1) cuando se expresa como 'copyWithZone envía un mensaje con el método (2). aka no tienes que hacer nada para obtener una zona tú mismo.

Ahora, como tiene una 'zona' enviada a este mensaje, puede usarla para asegurarse de que se hace una copia de la memoria en la misma región que el original.

Esto puede ser usado como:

-(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); 
} 

Este es el único lugar Soy consciente allocWithZone se utiliza realmente.

2

Yo uso allocWithZone en singleton. Como mencionó Forrest, las variables creadas se asignaron desde la misma región de memoria. Por lo tanto, otras clases pueden usar o acceder a ellos desde la misma zona de memoria. Ahorre espacio en la memoria cuando ejecuta su aplicación.

27

De documentation de Apple:

Este método existe por razones históricas; las zonas de memoria ya no son utilizadas por Objective-C.

2

En el Foundation Functions Reference, todas las funciones Zone ahora están precedidos por la siguiente advertencia de que serán ignorados Zonas.

Las zonas se ignoran en iOS y el tiempo de ejecución de 64 bits en OS X. No debe usar zonas en el desarrollo actual.

NSCreateZone 
NSRecycleZone 
NSSetZoneName 
NSZoneCalloc 
NSZoneFree 
NSZoneFromPointer 
NSZoneMalloc 
NSZoneName 
NSZoneRealloc 
NSDefaultMallocZone 
0

Incluso si la documentación de Apple indica que allocWithZone:

existe por razones históricas; las zonas de memoria ya no son utilizadas por Objective-C. No debes anular este método.

y

zonas son ignorados en IOS y 64 bits en tiempo de ejecución en OS X. No se deben utilizar las zonas de desarrollo actual.

en realidad me anulados en una clase de Objective-C (en un proyecto lleno de Objective-C) y el método es llamado cuando lo haga [[Mylass alloc] init] incluso si la acumulación se ejecuta en un iPhone 6s.

Pero creo que es mejor seguir la documentación y reemplazar el método alloc en lugar de este porque alloc ciertamente puede hacer el mismo trabajo.

Cuestiones relacionadas