2010-09-06 12 views

Respuesta

21

por lo que sé que no hay una clase genérica avaialbe. Intente utilizar NSMutableArray, agregue mediante addObject y obtenga first/last a través de objectAtIndex y removeObjectAtIndex.

1

Sí, un NSMutableArray se dobla como una pila o cola. (Sería poco ineficaz como una cola.)

También es posible usar stack y queue adaptador de C++ 's, pero hace que la gestión de memoria un poco desordenado si desea almacenar objetos Objective-C con él.

0

No. No se ha perdido nada. Eso es todo. Objective-C es un lenguaje de nivel más alto similar a C. No se requiere control de bajo nivel.

Las clases de cacao están diseñadas para un uso más fácil que la eficiencia. Si desea lidiar con el rendimiento, tiene una opción de implementación C (o C++) sin formato. De lo contrario, solo usa la manera fácil. Por supuesto, la optimización temprana es malvada.

Si desea un tipo de encapsulamiento, simplemente cree una nueva clase que contenga NSMutableArray. Oculte NSMutableArray interno y exponga lo que desea. Pero te darás cuenta de que esto es innecesario.

+1

Gracias. Me preocupa la duplicación de código, en lugar de la encapsulación. –

+0

¡NO usar una cola es malo! ¿Tienes alguna idea del impacto que tiene? Los arreglos NSMutable NO están diseñados para facilitar el uso (¡por cierto, no son fáciles de usar!), En realidad son eficientes y, como se mencionó anteriormente, se pueden usar para implementar colas. –

+1

@PizzaiolaGorgonzola Lo siento, pero es muy difícil entender lo que realmente quiere decir en este comentario. Y nunca dije que las clases de Cocoa son * ineficaces *. Lo que dije fue que las clases de Cocoa son relativamente menos eficientes y más fáciles de usar que sus contrapartes de nivel C (o C++). – Eonil

28

Aquí está mi clase de pila, en caso de que sea útil para los que me siguen. Como puede ver, el método pop involucra suficiente código que le gustaría restarle importancia.

Stack.h:

#import <Foundation/Foundation.h> 

@interface Stack : NSObject { 
    NSMutableArray *contents; 
} 

- (void)push:(id)object; 
- (id)pop; 

@end 

Stack.m

#import "Stack.h" 

@implementation Stack 

// superclass overrides 

- (id)init { 
    if (self = [super init]) { 
     contents = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 

- (void)dealloc { 
    [contents release]; 
    [super dealloc]; 
} 

// Stack methods 

- (void)push:(id)object { 
    [contents addObject:object]; 
} 

- (id)pop { 
    id returnObject = [[contents lastObject] retain]; 
    if (returnObject) { 
      [contents removeLastObject]; 
    } 
    return [returnObject autorelease]; 
} 

@end 
+2

Para el método pop, puede guardar un poco escribiendo usando [contents lastObject]. Eso devolverá nil si la matriz está vacía. Terminé implementando los métodos como una categoría en NSMutableArray. Gracias por el código! –

+0

Suena bien, gracias por la sugerencia. –

+1

Personalmente, probablemente solo agregue el método 'pop' a' NSMutableArray' a través de una categoría y use 'NSMutableArray' directamente donde necesite una pila, en lugar de crear una clase' Stack' completamente nueva. La mayoría de los lenguajes que he usado antes no tienen clases de pila dedicadas y usan matrices como pilas. Supongo que puedo ver la elegancia desde una perspectiva de legibilidad de tener una clase que * solo * se puede usar como una pila. –

6

Otra manera fácil sería para ampliar las capacidades NSMutableArray 's, haciendo uso de categorías objetivo de C. Puede hacerlo mediante la adición de dos archivos a su proyecto:

NSMutableArray + Stack.h

@interface NSMutableArray (StackExtension) 

- (void)push:(id)object; 
- (id)pop; 

@end 

NSMutableArray + Stack.m

#import "NSMutableArray+Stack.h" 

@implementation NSMutableArray (StackExtension) 

- (void)push:(id)object { 
    [self addObject:object]; 
} 

- (id)pop { 
    id lastObject = [self lastObject]; 
    [self removeLastObject]; 
    return lastObject; 
} 

@end 

ya se puede utilizar un habitual NSMutableArray en cualquier otro archivo de su proyecto como una pila y llame al push o pop en ese objeto.No se olvide de #import NSMutableArray+Stack.h en esos archivos. Aquí hay un código de ejemplo de cómo se puede utilizar el nuevo NSMutableArray como una pila:

NSMutableArray *myStack = [[NSMutableArray alloc] init]; // stack size = 0 

NSString *aString = @"hello world"; 
[myStack push:myString];   // stack size = 1 

NSString *anotherString = @"hello universe"; 
[myStack push:anotherString];  // stack size = 2 

NSString *topMostStackObject; 

topMostStackObject = [myStack pop]; // stack size = 1 
NSLog("%@",topMostStackObject); 

topMostStackObject = [myStack pop]; // stack size = 0 
NSLog("%@",topMostStackObject); 

será la salida del registro:

hello universe 
hello world 
1

ObjectiveSugar es una CocoaPod muy popular que ofrece, entre un montón de otras gran cosa, push y pop API llama al NSMutableArray. Claro, no está en el SDK de iOS, pero lo estoy compartiendo aquí porque estaba buscando lo mismo, y esta fue la solución con la que trabajé (y desde luego no me dolió que ya estuviéramos usando este CocoaPod en nuestro base de código).