黑马程序员_OC中的Foundation框架学习

来源:互联网 发布:java导入excel文件 编辑:程序博客网 时间:2024/06/06 00:38

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------


Foundation框架是Cocoa的一部分,没有内置于Objective-C中,但他仍然十分重要。Foundation中有很多有用的、面向数据的简单类和数据类型,例如:NSString、NSArray、NSNumber。

一些有用的数据类型


Cocoa为我们提供了一些非常有用的结构体。

范围

1. 结构体NSRange
typedef struct _NSRange{      unsigned int location;      unsigned int length;} NSRange;

这个结构体用来表示相关事物的范围,通常是字符串里的字符范围或数组里的元素范围。Location字段存放该范围的起始位置,而length字段则是该范围内所含元素的个数。
创建新的NSRange有三种方式:
1)直接给字段赋值:
NSRange range;range.location = 17;range.length = 4;

2) 应用C语言的聚合结构赋值机制:
NSRange range = {17, 4};

3) Cocoa提供的一个快捷函数NSMakeRange():
NSRange range = NSMakeRange(17, 4);

使用NSMakeRange()的好处是你可以在任何能够使用函数的地方使用它,比如在方法调用中将其做为参数进行传递。
[anObject flarbulateWithRange: NSMakeRange(17, 4)];

几何数据类型

我们经常会看到用来处理集合图形的数据类型,它们的名称都带有CG前缀,如CGPoint和CGSize。这些类型是由Core Graphics框架提供的,用来进行2D渲染。Core Graphics是C语言所写的,因此可以在代码中使用C语言的数据类型。CGPoint表示的是笛卡尔平面中的一个坐标(x, y)。

struct CGPoint{      float x;      float y;};CGSize用来存储长度和宽度:struct CGSize{      float width;      float height;};

Cocoa提供了一个矩形数据类型,它由坐标和大小复合而成。

struct CGRect{     CGPoint origin;     CGSize size;};

Cocoa也为我们提供了创建这些数据类型的快捷函数: CGPointMake()、CGSzieMake()、CGRectMake()。

补充:为什么这些数据类型是C的struct结构体而不是对象呢?原因就在于性能。程序(尤其是GUI程序)会用到许多临时的坐标、大小和矩形区域来完成工作。而所有的OC对象都是动态分配的,而动态分配是一个代价较大的操作,它会消耗大量的时间。所以将这些结构体创建而第一级的对象会在使用过程中大大增加系统开销。

字符串

字符串是一组可读的字符序列。C语言将字符串做为简单的字符数组进行处理,并且在数组的最后添加尾部的零做为结束标志。而Cocoa中的NSString则有很多的内置方法,简化了字符串的处理。

创建字符串

NSString的stringWithFormat:方法通过格式字符串和参数来创建NSString。

+ (id)stringWithFormat:(NSString *) format, ...;

可以按如下方式创建一个新的字符串:

NSString * height;height = [NSString stringWithFormat:@"Your height is %d feet, %d inches", 5, 11];

得到的字符串是 "Your height is 5 feet, 11 inches"。

关于字符串的大小

NSString中另一个好用的方法(实例方法)是length,他反回的是字符串中的字符个数。

- (NSUInteger) length;

可以这样使用它:

NSUInteger length = [height length];

补充:NSString的length方法可以精确无误的处理各种语言的字符串,如中文或者日文等的字符串,以及使用Unicode国际字符标准的字符串。在C语言中处理这些国际字符串是件令人头疼的事,因为一个字符占用的空间可能多于一个字节,这就意味着strlen()之类只计算字节数的函数会返回错误的数值。

字符串比较

isEqualToString:可用来比较接收方(receiver,接收消息的对象)和作为参数传递过来的字符串。isEqualToString:返回一个BOOL值来表示字符串的内容是否相同。它的声明如下:

- (BOOL) isEqualToString: (NSString *)aString;

使用方法如下:

NSString *thing1 = @"hello 5";NSString *thing2 = [NSString stringWithFormat: @"hello %d", 5];if([thing1 isEqualToString: thing2]){       NSLog(@"They are the same!");}

比较两个字符串,可以使用compare:方法,其声明如下:

- (NSComparisonResult) compare: (NSString *) aString;

compare:将接收对象和传递过来的字符串逐个进行比较,它返回一个NSComparisonResult来显示比较结果。

字符串是否还包含别的字符串

有时候我们可能想看看字符串内是否包含另一个字符串。例如,想知道某个文件的后缀名是否是.mp3。有两个方法,hasPrefix:检查字符串是否以一个字符串开头。hasSuffix:检查字符串是否以某个字符串结尾。

- (BOOL) hasPrefix: (NSString *)aString;- (BOOL) hasSuffix: (NSString *)aString;

可以按如下方式使用这两个方法:

NSString *fileName = @"draft-chapter.pages";if([fileName hasPrefix: @"draft"){     // this is a draft}if([fileName hasSuffix: @".mp3"]){     // this is a music}

如果想知道字符串的某处是否包含其他字符串,可以使用rangeOfString:。

- (NSRange)rangeOfString: (NSString *)aString;

将rangeOfString:发送给一个NSString对象时,传递的参数时要查找的字符串。它会返回一个NSRange结构体,告诉你这个字符串匹配的部分在哪里以及匹配的个数。

可变字符串

NSString是不可变(immutable)的,意味着一旦被创建,便不能改变。Cocoa提供了一个NSString的子类,叫做NSMutableString,它可以改变字符串。

可以使用类方法stringWithCapacity:来创建一个新的NSMutableString,其声明如下:

+ (id) stringWithCapacity: (NSUInteger)capacity;

这个容量只是给NSMutableString一个建议,可以超过其大小。可按如下方式创建一个新的可变字符串:

NSMutableString *string = [NSMutableString stringWithCapacity: 40];

一旦创建了一个可变字符串,就可以执行各种操作了。如通过appendString:或appendFormat:来附加新的字符串,如下:

- (void) appendString: (NSString *)aString;- (void) appendFormat: (NSString *)format, ...;

appendString:接收参数aString,然后将其复制到接收对象的末尾。appendFormat:与stringWithFormat:类似,但并没有创建新的字符串,而是将格式化的字符串附加在了接收字符串的末尾。例如:

NSMutableString *string = [NSMutableString stringWithCapacity:50];[string appendString: @"Hello there "];[string appendFormat: @"huaman %d!", 39];

string最后为 "Hello there huaman 39"。

deleteCharactersInRange:被用来删除字符串中的字符。

- (void) deleteCharactersInRange: (NSRange)aRange;

集合大家族

Cocoa提供了许多集合类,如NSArray和NSDictionary,它们的实例就是为了存储其他对象而存在的。

NSArray

NSArray是一个Cocoa类,用来存储对象的有序列表。可以在NSArray中放入任意类型的对象。

NSArray类有两个限制。1,只能存储OC对象,而不能存储原始的C语言基础数据类型,如int , float, struct, enum和NSArray中的随机指针。2,不能在NSArray中存储nil(对象的零值或NULL值)。可以通过类方法arrayWithObjects:创建一个新的NSArray。发送一个以逗号分隔的对象列表。在结尾处添加nil代表列表的结束(这就是为什么不能在数组中存储nil的一个原因)。

NSArray *array = [NSArray arrayWithObjects: @"one", @"two", @"three", nil];

也可以使用数组字面量格式来创建一个数组。如下:

NSArray *array2 = @[@"one", @"two", @"three"];

这种方法不必在结尾处写上nil。

获取对象的个数:

- (NSUInteger) count;

获取特定索引处的对象:

- (id)objectAtIndex: (NSUInteger)index;

通过字面量访问数组的语法与C语言中的访问数组项的语法类似。

id *myObject = array[1];

结合计数和其取值来输出数组中的内容:

for(NSUInteger i = 0; i < [array count]; i++){      NSLog(@"index %d has %@.", i, [array objectAtIndex: i]);}

你可以使用数组字面量语法,如:

for(NSUInteger i = 0; i < [array count]; i++){      NSLog(@"index %d has %@.", i, [array i]);}

可变数组

与NSString一样,NSArray创建的是不可变对象的数组。NSMutableArray是一个可变数组类,可以随意添加或删除数组中的对象。通过类方法arrayWithCapacity来创建新的可变数组:

+ (id) arrayWithCapacity: (NSUInteger)numItems;

使用addObject:在数组末尾添加对象:

- (void) addObject: (id) anObject;

如下代码,循环添加4个轮胎对象:

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

removeObjectAtIndex:用来删除对象:

- (void) removeObjectAtIndex: (NSUInteger) index;

如:

[array removeObjectAtIndex: 1];

NSDictionary

字典是关键字及其定义的集合。Cocoa中有一个实现这种功能的集合类NSDictionary。NSDictionary能在给定的关键字(通常是一个NSString字符串)下存储一个数值(可以是任意类型的OC对象),然后就可以通过这个关键字查找相应的数据。可以通过dictionaryWithObjectsAndKeys:来创建字典:

+ (id) dictionaryWithObjectsAndKeys: (id)firstObject, ...;

该方法接收对象和关键字交替出现的序列,以nil作为终止符。

也可以使用字面量语法类似@{key:valaue, ...}的方法来定义。注意是大括号,而且先存储对象,再是关键字。而且不需要nil结束。

NSMutableDictionary

创建NSMutableDictionary有两种方法:

1)dictionaryWithCapacity:方法创建:

+ (id) dictionaryWithCapacity: (NSUInteger) numItems;

2) 向NSMutableDictionary类发送dictionary消息。如:

NSMutableDictionary *tires = [NSMutableDictionary dictionary];

使用setObject:forKey:方法为字典添加元素:

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

使用方法如下:

[tires setObject: t1 forKey: @"front-left";

如锅字典中已有关键字使用setObject:forKey:方法,那么这个方法会用新值替换原来的数值。

如果想在可变的字典中删除一些关键字,可以使用removeObjectForKey:方法:

与NSArray一样,没有适用于NSMutableDictionary的字面量初始化方法。

注意:请不要创建NSString、NSArray或NSDictionary的子类。


其他数值

NSArray和NSDictionary只能存储对象,而不能直接存储基本类型的数据。不过我们可以用对象来封装基本数值。如可以使用NSInteger和NSUInteger。

NSNumber

Cocoa提供了NSNumber类来封装基本数据类型。可以使用以下方法来创建新的NSNumber对象:

+ (NSNumber) numberWithChar: (char)value;+ (NSNumber) numberWithInt: (int)value;+ (NSNumber) numberWithFloat: (float)value;+ (NSNumber) numberWithBool: (BOOL)value;

还有许多这样的创建方法。包括无符号整数以及long long等。

也可以使用字面量语法来创建这些对象。

NSNumber * number;number = @‘X’;//字符类型number = @12345;//整数number = @12345ul;//无符号长整数number = @12345ll;//long longnumber = @123.45f;//浮点型number = @123.45;//双浮点型number = @YES;//布尔型

创建完NSNumber之后,可以放入一个字典或数组中:

NSNumber *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对象。

+ (NSValue *) valueWithBytes: (const void *) value objCType: (const char *) type; 

传递的参数是你想要封装的数值的地址(如一个NSSize或一个struct)。通常得到的是想要存储变量的地址(C语言中使用&)。你也可以提供用来描述这个数据类型的字符串,通常用来说明struct中实体的类型和大小。你不用自己写代码来生成这个字符串,@encode编译器指令可以接收数据类型的名称并为你生成合适的字符串,如下:

NSRect rect = NSMakeRect(1, 2, 30, 40);NSValue *value = [NSValue valueWithBytes:&rect objCType: @encode(NSRect)];[array addObject: value];

使用getValue:来提取数值:

- (void) getValue: (void *)buffer;

调用getValue:时,需要传递存储这个数值的变量地址:

value = [array objectAtIndex: 0];[value getValue: &rect];

Cocoa提供了常用的struct类型数据转换成NSValue的便捷方法:

+ (NSValue *)valueWithPoint: (NSPoint)aPoint;+ (NSValue *)valueWithSize: (NSSize)size;+ (NSValue *)valueWithRect: (NSRect)rect;- (NSPoint)pointValue;- (NSSize)sizeValue;- (NSRect)rectValue;

NSNull

上面提到过集合中不能放入nil值,因为在NSArray和NSDictionary中nil有特殊的含义,但有时确实需要存储一个表示“这列什么都没有”的值。这就可以使用NSNull。它只有一个方法:

+ (NSNull *)null;

可以照下面的方式将它添加到集合中:

[contact setObject: [NSNull null] forKey: @"home fax machine"];

访问方式如下:

id home fax = [contact objectForKey: @“home for machine”];if(home fax == [NSNull null]){//……..}

[NSNull null]总是返回一样的数值,所以你可以使用运算符==将该值与其他值进行比较。

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

0 0