2012-01-02 16 views
9

Quiero crear una subclase de NSMutableArray y necesito anular el método -initWithObjects:.Missin centinela en el envío del método

Pero ¿Cómo llamar a [super xxx] ;?

- (id) initWithObjects:(id)firstObj, ... { 
    [super initWithObjects:firstObj]; // Error: Missing sentinel in method dispatch 
    // Error: The result of a delegate init call must be immediately returned or assigned to "self" 

} 

Thanks.

Respuesta

10

No se puede. Como se discutió en the documentation for NSArray:

Es posible que desee poner en práctica un inicializador para su subclase que es adecuado para el almacén de respaldo que la subclase es la gestión. La clase NSArray no tiene un inicializador designado, por lo que su inicializador necesita solo invoca el método init de super. La clase NSArray adopta los protocolos NSCopying, NSMutableCopying y NSCoding; si desea instancias de su propia subclase personalizada creada a partir de copiar o codificar, anula los métodos en estos protocolos.

Así que puede asignar self = [super init]; y agregar los objetos de su inicializador al objeto resultante. De hecho, debido a la forma en que se implementa NSArray, llamar a cualquier método -initWith… es probable que devuelva una instancia de una diferenteNSArray subclase.

Observe que la documentación también analiza las alternativas a la subclase NSArray que pueden ser más fáciles, más confiables o mejores de alguna otra manera.

-1

Trate

self = [super initWithObjects:firstObj,nil]; 
+0

resolviste el problema delegado, pero todavía hay una advertencia de falta de centinela ... –

+0

Intenté 'self = [super initWithObjects: firstObj, nil];' y la advertencia desapareció, pero ¿faltará el objeto dentro de la matriz? cuando se llama a esta subclase? –

+0

Sí, lo siento, debe agregar nil al final. Lo siento pero no entiendo tu pregunta ... – Saphrosit

2

La subclasificación NSArray/NSMutableArray no funciona como subclases de la mayoría de las clases. NSArray es un clúster de clase, consulte subclassing notes de la documentación NSArray.

Ahora, para su pregunta específica, la subclasificación va_list métodos es un poco complicado, hay una serie de maneras de manejar esto. Lo más 'seguro' sería procesar su va_list en un NSArray y pasarlo a otro método que tratara con lo que usted quisiera. La otra, un poco menos portátil, un poco más hackier es crear una nueva lista va_list en la pila para pasar.

id __unsafe_unretained * stack = (typeof(stack))calloc(numOfObjects, sizeof(id)); 
    //filloutStack 
    [super initWithObjects:*stack, nil]; 
    free(stack); 
2

subclases Manzanas clases de colección no es tan difícil - si se utiliza un pequeño truco (véase también: cocoawithlove).

Una subclase es una relación "is-a" en el diseño orientado a objetos. Pero también hay relaciones "has-a", es decir, envoltorios.

Si intentas crear una subclase de NSArray utilizando una relación pura es, supongo que sería un poco difícil, ya que tendrías que hacer una gestión de memoria de nivel C.

Pero si agrega una relación has-a - o: cree un contenedor - al mismo tiempo, puede hacer el subcalssing con bastante facilidad: Simplemente haga que su clase de matriz personalizada tenga un miembro de un NSArray normal. Ahora anule su método reenviando las llamadas al objeto miembro.Mostré esto in this post, where I just add objects, that pass a certain test.

Pero verá que no implementé el método del que habló correctamente, pero me genera un error. La razón es: ese método es un método variadic, que tiene una cantidad variable de objetos que puede pasar, y para manejar esto, debe trabajar un poco. cocoawithlove has an great article about it.

Para que - si se utiliza que tiene-un truco - que podría parecerse a

- (id) initWithObjects:(id)firstObj, ... { 

    if (self = [super init]) { 
     _realArray = [[NSMutableArray alloc] initWithCapacity:1]; 
    } 

    va_list args; 
    va_start(args, firstObj); 
    for (id obj = firstObj; obj != nil; obj = va_arg(args, id)) 
    { 
     [self.realArray addObject:obj]; 
    } 
    va_end(args); 
    return self; 
} 
+0

He probado este código y he reparado algún problema. Ahora trabajando. – vikingosegundo

42

Entonces "falta centinela" mensaje se refiere a la terminación nula faltante. De hecho, de acuerdo con font-de-todo-conocimiento-Wikipedia:

El nombre de la nil que termina una lista de longitud variable de parámetros en Objective-C

también: nodo Sentinel, un objeto para representar la final de una estructura de datos también: valor centinela, un valor utilizado para terminar un bucle también: En protocolos de red como Bisync, los valores centinela indican dónde fotogramas inicial y final

Cuestiones relacionadas