——- android培训、IOS培训、期待与您交流! ———-
集合
Cocoa提供了许多集合类,如NSArray和NSDictionary,它们的实例就是为了储存其它对象而存在的。
NSArray
NSArray是一个Cocoa类,用来存储对象的有序列表。可以在NSArray中放入任意类型的对象:NSString、Car、Shape、Tire或者其它对象,甚至可以是其它数组或字典对象。
NSArray有两个限制。首先,他只能存储Objective-C对象,而不能存储原始的C语言基础数据类型,如int、float、enum、struct和NSArray中的随机指针,也不能在NSArray中存储nil(对象的零值或NULL值)。
可以通过类方法arrayWithObjects: 创建一个新的NSArray。发送一个以逗号分隔的对象列表,在列表的结尾加nil代表列表结束。
NSArray *array = [NSArray arrayWithObjects: @"one", @"two", @"three", nil];
或
NSArray *array2 = @[@"one", @"two", @"three"];
只要有了一个数组,就可以获取它所包含的对象个数:
- (NSUInteger) count;
也可以获取特定索引出的对象:
- (id) objectAtIndex: (NSUInteger) index;
与C语言的语法类似。
id *myObject = array1[1]
可以结合计数和取值功能来输出数组中的内容:
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]);
可变数组
NSArray创建的是不可变对象的数组。一旦创建一个包含特定数量的对象的数组,它就固定下来了:既不能添加任何元素也不能删除任何元素。数组中包含的对象可以改变,但数组对象本身一直都是不会改变的。
NSMutableArray是可变数组类,可以随意地添加或删除数组中的对象。NSMutableArray通过类方法arrayWithCapacity来创建新的可变数组:
+ (id) arrayWithCapacity: (NSUInteger) numItems;
可以按照如下创建可变数组:
NSMutableArray *array = [NSMutableArray arrayWithCapacity: 17];
使用addObject: 在数组末尾添加对象:
- (void) addObject: (id) anObject;
用法:
for (NSIntrger i = 0; i < 4; i++)
{
Tire *tire = [Tire new];
[array addObject: tire];
}
可以用remoeOnjectAtIndex:
删除特定索引处的对象:
-(void) removeObjectAtIndex: (NSUInteger) index;
用法:
[array removeObjectAtIndex: 1];
注意: NSArray中的对象是从零开始编制索引的。
枚举
Cocoa用NSEnumerator来表示集合中迭代出的对象。要使用NSEmumerator,要通过objectEnumerator向数组请求枚举器:
- (NSEmunerator) objectEnumerator;
可以这样:
NSEnumerator *enumerator = [array objectEnumerator];
如果想要从后往前浏览莫个集合,可以使用reverseObjectEnumerator方法.
在获得枚举器之后,就可以开始一个while循环,每次循环都向这个枚举器请求nextObject:
- (id) nextObject;
nextObject返回nil
时,循环结束。
NSEnumerator *enumerator = [array objectEnumerator];
while (id thingie =[enumerator nextObject])
{
NSLog (@"I found %@",thingie);
}
快速枚举
快速枚举的改进代码如下:
for (NSString *string in array)
{
NSLog (@"I found %@", string);
}
循环体遍历数组中的每一个元素,用变量string存储每个数组值。
NSDictionary
在编程中,字典(dictionary)是关键字及其定义的集合。NSDictionary能在给定的关键字下存储一个数值。然后就可以用这个关键字来查找相应的数据。
+ (id) dictionaryWithObjectsAndKeys: (id) firstObject,...;
该方法接收对象和关键字交替出现的序列,以nil
值作为终止符号。
Tire *t1 = [Tire new];
Tire *t2 = [Tire new];
Tire *t3 = [Tire new];
Tire *t4 = [Tire new];
NSDictionary *tires = [NSDictonary dictionaryWithObjectsAndKeys: t1,@"front-left", t2,@"front-right", t3, @"back-left", t4,@"back-right",nil];
或者
NSDictionary *tires = @{@"front-left" : t1, @"front-right" : t2, 2"back-left" : t3, @"back-right" : t4};
查找:
Tire *tire = [tires objectForkey: @"back-right"];
或者:
Tire *tire = tires[@"back-right"];
NSNumber
Cocoa提供NSNumber
类来封装基本数据类型。
+ (NSNumber *) numberWithChar: (char) value;
+ (NSNumber *) numberWithInt: (int) value;
+ (NSNumber *) numberWithFloat: (float) value;
+ (NSNumber *) numberWithBool: (BOOL) value;
创建完NSNumber
后,可以放入一个字典或数组中:
NSNUMER *NUMBER = @42;
[array addObject number];
[dictionary setObject: number forKey: @"Bork"];
在将一个基本类型数据封装到NSNumber中后,可以通过下面的实例方法来重新获得它:
- (char) charValue;
- (int) intValue;
- (float) floatValue;
- (BOOL) boolValue;
- (NSString *) stringValue;
NSValue
NSNumber实际是NSValue的子类,NSValue可以封装任意值。可以使用NSValue将结构体放入NSArray或NSDictionary中。方法如下:
+ (NSValue *) valueWithBytes: (const void *) value objCType: (const char *) type;
传递的参数是想要封装的数值的地址(如一个NSSize或一个struct)。通常得到的是想要储存的变量的地址(在C语言中要使用操作符&
)。
NSRect rect = NSMakeRect (1, 2, 30, 40);
NSValue *value = [NSValue valueWithBytes: &rect objeCType: @encode(NSRect)];
[array addObject:value];
可以使用方法getValue:
来提取数值:
- (void) getValue: (void *) buffer;
调用getValue:
时,需要传递储存这个数值的变量地址:
value = [array objectAtIndex: 0];
[value getValue: &rect];
查找文件
程序FileWalker可以访问主目录查找.jpg文件并打印到列表。
int main(int argc, const char *argv[])
{
@autoreleasepool
{
NSFileManager *manager;
manager = [NSFileManager defaultManager];
NSString *home;
home = [@"~" stringByExpandingTildeInPath];
NSDirectoryEnumerator *direnum;
direnum = [manager enumeratorAtPath: home];
NSMutableArray *files;
files = [NSMutableArray arrayWithCapacity: 42];
NSString *filename;
while (filename = [direnum nextObject])
{
if ([[filename pathExtension] isEqualTo: @"jpg"])
{
[files addObject: filename];
}
}
NSenumerator *fileenum;
fileenum = [file objectEnumerator];
while (filename = [fileenum nextObject])
{
NSLog(@"%@", filename);
}
}
return 0;
} // main
最上面是自动释放池(@autoreleasepool
)。然后是获取NSFileManager对象。defaultManager
类方法可以创建一个NSFileManager
对象。
Unix系统有一个代表主目录的速记符号~
, stringByExpandingTildePath
接收~
字符并将其展开成主目录路径。
接下来将路径字符串传递给文件管理器, enumeratorAtPath:
返回一个NSDictionaryEnumerator对象,它是NSEnumerator的子类。每次在这个枚举器对象中调用nextObject方法时,都会返回该目录中下一个文件的路径。迭代循环结束时,将会得到主目录中每一个文件的路径。
要查找.jpg文件(即路径名称以.jpg结尾)并输出它们的名称,需要存储这些名称的空间。使用NSMutableArray创建一个可变数组并将查找到的路径添加进去。容量参数并不限制数组的大小,这里使用了42
。
目录枚举器将返回一个代表文件路径的NSString字符串。就像NSEnumerator一样,当枚举器结束时它会返回nil值终止循环。
pathExtension方法能输出文件的扩展名。这里使用嵌套的方法调用获取路径扩展名并将获得的字符串传递给isEqualTo:方法 。如果该调用的返回结果是YES,则该文件名将会被添加到文件数组中。
目录循环结束后,遍历文件数组,用NSLog()函数将数组内容输出。
最后main()
函数返回0退出程序。
快速枚举方法
使用快速枚举方法可以将已有的NSEnumerator对象或器子类传递给它。
int main(int argc, const char *argv[])
{
@autoreleasepool
{
NSFileManager *manager;
manager = [NSFileManager defaultManager];
NSString *home;
home = [@"~" stringByExpandingTildeInPath];
NSMutableArray *file;
files = [NSMutableArray arrayWithCapacity: 42];
for(NSString *filename in [manager enumeratorAtPath: home])
{
if([[filename pathExtensions] isEqualTo: @"jpg"])
{
[files addObject: filename];
}
}
for(NSString *filename in files)
{
NSLog(@"%@", filename);
}
}
reutrn 0;
} // main
这个版本省略了两个枚举器变量及其支持代码,从而变得更简单了。