iOS学习之集合

jopen 10年前
NSArray

NSArray是一个Cocoa类,是用来存储对象的有序列表的,可以在有序列表中存放任意类型的对象。
NSArray有两个限制,首先是只能存储Objective-c对象,而不能存储原始的C语言数据对象比如说:int,float,struct,enum和NSArray中的随机指针,当然也不能在NSArray中保存nil。
可以通过arrayWithObjects创建一个新的NSArray。发送一个以逗号分割的列表对象,在列表解结尾添加nil代表列表的结束(这就是不能在NSArray中添加nil的原因)
NSArray *array = [NSArray arrayWithObjects:@“one”,@“two”,@“three“,nil]
也可以使用NSString来创建数组,比如
NSArray *array2 = @[@“one”,@“two”,@“three”]
显然后者的代码量小于前者,然而两者的内容是一样的。
只要有了一个数组就可以获得它所包含的对象个数
- (NSUInteger) count
也可以获得特定索引处的对象:
- (id) objectAtIndex:(NSUInteger) index
字面上的赋值方法和C语言一样
id *myObject = array[1];
可以通过循环的方法遍历数组
NSArray *array = [NSArray arrayWithObjects:@"one",@"two",@"three",nil];
for (NSInteger i = 0; i < [array count]; i++) {
     
NSLog(@"index %d has %@",i,[array objectAtIndex:i]);
}

当然也可以使用数字变量来循环
for (NSInteger i = 0; i < [array count]; i++) {
     
NSLog(@"index %d has %@",i,array[i]);
}

在array[i]中i的值要是超过了索引值就会报错。

可以使用componentsSeparatedByString将字符串切割成数组
NSString *string = @“oop:ack:bork:greeble:ponies”;
NSArray *chunks = [string componentsSeparatedByString:@“:”];
这时chunks是[‘oop’,’ack’,’bork’,’greeble’,’ponies’]的NSArray数组
还可以使用componentsJoinedByString来合并数组
string = [chunk componentsJoinedByString:@“:)”];
这时,string的值就是”oop:)ack:)bork:)greeble:)ponies:)”的NSString字符串

可变数组

与NSString一样,NSArray创建的数组是不可变的,一旦创建了就不能添加或者删除任何元素,为了弥补NSArray的不足,也出现了NSMutbleArray这个可变数组的类,这样就可以通过arrayWithCapacity添加或者删除元素。

+ (id) arrayWithCapacity:(NSUInteger) numItems;

与stringWithCapacity一样,书组容量也只是一个参考值,容量存在的意义就是让Cocoa能够对代码进行优化

NSMutableArray *array = [NSMutableArray arrayWithCapacity:17];

使用addObject在末尾添加对象

- (void) addObject:(id) anObject;

比如要添加四个轮胎

for (NSInteger i = 0; i<4; i++) {
     Tire *tire = [Tire new];
     [array addObject:tire];
}


也可以删除索引处特定的对象

-(void) removeObjectAtIndex:(NSUInteger) index;

如果要删除第二个对象:

[array removeObjectAtIndex:1]


枚举

NSArray 经常要对数组中的每个元素都执行同一个操作,比如给每个元素的值+1,也可以都*1,—1等等。可以编写一个循环体从0到[array count]来读取每个索引来进行处理,也可以使用NSEnumerator,Cocoa可以用它来表示集合中迭代出的对象。使用 NSEnumerator需要通过objectEnumerator向数组请求枚举器。

- (NSEnumerator *) objectEnumerator;
NSEnumerator *enumerator = [array objectEnumerator];

如果是从后向前x循环,还有一个reverseObjectEnumerator方法。
在获得枚举器之后,便可以开始一个while循环体每次循环都可以向它请求nextObject

- (id) nextObject;

nextObject返回一个nil值时,训话结束,这也是数组中不能存储nil的另一个原因,没有办法判断nil是存储在书组中的数值还是循环结束的标识。

while (id thingie = [enumerator nextObject]) {
       NSLog(
@"I found %@",thingie);
}

ps.这段代码不知怎么的会提示unexpected type name ‘id’...

快速枚举
快速枚举的语法感觉和python差不多,例如

for (NSString *string in array) {
     
NSLog(@"I found %@ also",string);
}

这个循环体将会遍历数组,并且用变量string来存储数组变量的值,这种枚举方法会更加简洁快速。

在最新版的苹果编译器为纯C语言添加了一个叫做代码块的特性,为了支持代码块苹果公司添加了一个能在NSArray中通过代码块枚举对象的方法

- (void) enumerateObjectsUsingBlock:(void (^) (id obj,NSUInteger idx,BOOL *stop))block;

这时,有四种方法来遍历数组了:
1、通过索引
2、使用NSEnumerator
3、使用快速枚举
4、代码块

NSDictionart

字典,在Python中有定义:

字典是另一种可变容器模型,且可存储任意类型对象,如其他容器模型。

字典由键和对应值成对组成。字典也被称作关联数组或哈希表。基本语法如下:

dict = {
'Alice''2341''Beth''9102''Cecil''3258'}
也可如此创建字典:

dict1 = { 
'abc'456 };
dict2 = { 
'abc'12398.637 };
每个键与值用冒号隔开(:),每对用逗号,每对用逗号分割,整体放在花括号中({})。

键必须独一无二,但值则不必。

值可以取任何数据类型,但必须是不可变的,如字符串,数或元组。

Objective- c中的字典也是关键字及其定义的集合。Cocoa中有一个实现这个功能的集合类NSDictionary.NSDictionary能够在一个关键字(通常是一个NSString字符串)下面存储一个数值(可以是任何的Objective-c对象),然后可以通过这个关键字来查找数值,例如电话簿,一个名字下面存储一个电话号码,我们可以通过好友的名字来查找好友电话,当然我们也可以存储好友的邮箱或者家庭住址等等。
还有一件有趣的事情,那就是NSDictionary同NSArray一样是不可变的对象,但是NSMutableDictionary可以允许随意添加删除字典中的关键字。
字典的最简单的方法就是用字典的字面量语法,它与类方法dictionaryWithObjectsAndKey非常相似。字面量语法就是 @{key:value,…},使用花括号来定义字典。还要注意dictionaryWithObjectsAndKey后面的参数首先是要存储的对象,然后才是关键字,数值在关键字后面,中间用冒号分开,每对键值用逗号分割开。以nil作为终止符,自然在字典中不能存储nil值。

+ (id) dictionaryWithObjectsAndKey:(id) firstObject,…;

假设我们要存钱,可以这样来写代码

Money *m1 = [Money new];
Money *m2 = [Money new];
Money *m3 = [Money new];
Money *m4 = [Money new];
NSDictionary *money = [NSDictionary dictionaryWithObjectsAndKeys:m1,@"first",m2,@"second",m3,@"third",m4,@"fourth",nil];
也可以这样子:  
NSDictionary *money = @{@"first":m1,@"second":m2,@"third":m3,@"fourth":m4};

可以使用方法objectForKey来传递关键字来获取对应的数值。

- (id) objectForKey:(id) aKey;

或者是

Money[key]

假设要查找第三次存钱的数目,可以这样

Money *cash = [money objectForKey:@"third"];
或者是
Money *cash = money[
@"third"];

如果是字典中没有的值则返回nil值。

向NSMutableDictionary发送dictionary消息可以创建一个新的NSMutableDictionary对象,还可以使用dictionaryWithCapacity来创建新的可遍字典来告诉Cocoa该字典的大小。

+ (id) dictionaryWithCapacity:(NSUInteger) numItems;

这个与之前的NSMutableArray和NSMutableString一样,这里的容量也只是个建议而不是限制,可以使用setObject:forkey来为字典添加元素。

- (void) setObject:(id) anObject forkey:(id)aKey;

因此,有另一种方法来记录存钱

Money *money = [NSMutableDictionary dictionary];
[money setObject:m1 forkey:
@"first"];
[money setObject:m2 forkey:
@"second"];
[money setObject:m3 forkey:
@"third"];
[money setObject:m4 forkey:
@"fourth"];

对字典中已经存在的关键字使用setObject:forkey可以替换原来的键值对,如果要删除某些关键字,可以使用removeObjectForKey

- (void) removeObjectForKey:(id) aKey

假设去将第三次存的钱取出来了,那么就要从字典里面删除

[money removeObjectForKey@"second"];