我正在编写一个iPhone应用程序,但我惊讶地发现在苹果的Foundation框架中似乎没有NSQueue或NSStack类。我看到使用NSMutableArray很容易自己实现这些功能,所以我会这么做,除非我漏掉了什么。我有漏掉了什么吗?
我正在编写一个iPhone应用程序,但我惊讶地发现在苹果的Foundation框架中似乎没有NSQueue或NSStack类。我看到使用NSMutableArray很容易自己实现这些功能,所以我会这么做,除非我漏掉了什么。我有漏掉了什么吗?
以下是我的Stack类,希望对后来的人有所帮助。可以看到,pop方法涉及足够多的代码,您需要将其分解。
Stack.h:
#import <Foundation/Foundation.h>
@interface Stack : NSObject {
NSMutableArray *contents;
}
- (void)push:(id)object;
- (id)pop;
@end
Stack.m
:栈(Stack)的实现,通常用于数据结构和算法问题。#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
据我所知,目前没有通用的类可用。尝试使用NSMutableArray,通过addObject添加元素,使用objectAtIndex获取第一个或最后一个元素,使用removeObjectAtIndex删除元素。
removeObjectAtIndex
是一个 O(n) 操作,因此当预期的项目数量较大时,这可能不是队列的最佳方法。使用链表(允许从任意点高效添加和删除)可能更好,但不幸的是,这是另一种常见的集合类型,缺少基础知识,因此您也必须实现它。 - Jules另一种简单的方法是通过使用Objective C的分类扩展NSMutableArray
的功能。您可以通过向项目添加两个文件来实现:
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
现在,您可以像使用堆栈一样,在项目的其他文件中使用常规的NSMutableArray
,并在该对象上调用push
或pop
。不要忘记在这些文件中#import NSMutableArray+Stack.h
。以下是一些示例代码,演示如何将新的NSMutableArray
用作堆栈:
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);
hello universe
hello world
我在GitHub上发布了一个可用的iOS Objective C队列对象。这段代码来自于不同的帖子,不是我的独创。
https://github.com/esromneb/ios-queue-object/
如果您发现任何问题,请fork一下,并提出pull request!
ObjectiveSugar是一个非常流行的CocoaPod,它提供了许多其他很棒的功能,其中包括在NSMutableArray
上调用push
和pop
API。当然,这不是iOS SDK中的内容,但我在这里分享它,因为我也在寻找同样的东西,而这正是我选择的解决方案(而且我们已经在我们的代码库中使用了这个CocoaPod,这当然没有伤害)。
没错,你没有漏掉什么。这就是全部。Objective-C 是一种高级语言,类似于 C 语言。不需要低级别的控制。
Cocoa 类设计用于更易于使用而不是效率。如果你想处理性能,可以选择原始的 C(或 C++)实现。否则,只需使用简单的方法即可。当然,过早地优化是有害的。
如果你想要一种封装,只需创建一个包含 NSMutableArray 的新类。隐藏内部的 NSMutableArray,并仅暴露你想要的。但是你会意识到这是不必要的。
pop
方法添加到NSMutableArray
中,并直接在需要堆栈的地方使用NSMutableArray
,而不是创建一个全新的Stack
类。我以前使用过的大多数语言都没有专用的堆栈类,而是使用数组作为堆栈。虽然我可以从可读性的角度看到只能用作堆栈的类的优雅之处。 - Mark Amery