Objective-C基础学习笔记——Foundation Kit

学习资料:Learn Objective-C on the Mac

Cocoa由两个框架组成:Foundation Kit和Application Kit。Application包含所有用户接口对象和高级类;Foundation框架中包含面向数据的低级类和数据类型,拥有100多个类,例如NSString,NSArray,NSEnumerator,NSNumber等。相关文档存放于/Developer/ADC Reference Library/documentation/index.html中。

1.常用数据类型

typedef struct _NSRange{

unsigned int location;

unsigned int length;

}NSRange;

表示相关事物的范围,比如字符串中字符范围或者数组中元素范围等。location是范围的起始位置,length元素个数。

创建方式:

NSRange range; range.location = 1; range.length = 4;

NSRange range = {1,4}; //C语言的聚合结构赋值机制

NSRange range = NSMakeRange(1,4); //可以在能够使用函数的任何地方调用NSMakeRange。

typedef struct _NSPoint{

float x; float y;

}NSPoint;

typedef struct _NSSize{

float width; float height;

}NSSize;

typedef struct _NSRect{

NSPoint origin; NSSize size;

}NSRect;

NSRect是一个矩形数据类型,NSPoint是起始点,NSSize存储长度和宽度。 NSMakeRect() NSMakePoint().

这些常用的数据类型是C的struct而不是对象,在很多程序(比如GUI程序)中有很多临时的点,大小和矩形去完成工作,所有的Objective-C对象都是动态分配的,这样是一个代价较高的操作,需要大量时间。

2.字符串

Cocoa处理字符串的类NSString和它的子类NSMutableString。

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

...指可以接受以逗号分开的多个参数。+指该方法为类方法,是属于类对象。Obj-C在生产一个类的时候会创建一个代表类的类对象,包含指向超类的指针,类名和指向类方法列表的指针。还包含一个long数据,为新创建的类实例对象指定大小。-来开始声明的为实例方法,这些实例方法可能在某个对象实例中运行。 如果某方法用来实现常规功能比如创建一个实例对象或者访问一些全局类数据,一般声明为类方法。

-(unsigned int)length; 它能够准确处理国际字符串。中文,日文以及用Unicode国际字符标准的字符串。而在C中处理这些国际字符串很麻烦,因为一个字符占用空间肯那个多于一个字节,strlen()只计算字节数的函数通常不行。

-(BOOL)isEqualtoString:(NSString *)str; 而==运算符只判断两个字符串指针数值,没有判断他们所指向的对象。

-(NSComparisonResult)compare:(NSString *)str options:(unsigned)mask;

NSComparisonResult是一个enum型数据

typedef enum _NSComparisonResult{

NSOrderedAscending = -1, NSOrderedSame, NSOrderedDescending

}NSComparisonResult;

options是一个位掩码,可以用位或|来加选项标记。NSCaseInsensitiveSearch不区分大小写字符,NSLiteralSearch区分大小写,NSNumericSearch比起字符串字符个数。

NSString *str1 = @"hello 1 world";

NSString *str2;

str2 = [NSString stringWithFormat:@"hello %d world",1];

if([str1 compare:str2

options:NSCaseInsensitiveSearch | NSNumericSearch]

== NSOrderedSame)

{}

NSString一旦创建了就不能改变。可以用它生成新的字符串,查找字符或者比较。但是不能删除或者添加字符。可变的类NSMutableString是NSString的子类。它们是在一个.h文件中。

+(id)stringWithCapacity:(unsigned)capacity;创建一个capacity容量的字符串。先预分配一块内存存储它,后续的操作速度会快很多。当然也可以用它父类NSString的类方法和实例方法都可以使用。

NSMutableString *friends;

friends = [NSMutalbeString stringWithCapacity:50];

[friends appendString:@"James lilei lucy"]; //添加字符串到对象末尾

NSRange range;

range = [friends rangeOfString:@"lilei"]; //查找str2在str1中的范围

range.length++;

[friends deleteCharactersInRange:(NSRange)range]; //通过范围 删除字符

3.集合

NSArray,NSMutalbeArray,NSEnumerator,NSDictionary

NSArray类是一个存储对象的有序列表。只存储Objective-C对象不存储C中基本数据类型(int,float,enum,struct)或者NSArray中随即指针。同时也不存储nil(对象的零值或者NULL值)。

NSArray *array = [NSArray arrayWithObjects:@"1",@"2",@"three",nil];是以nil结尾的。这就是不能存储nil的原因之一。

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

-(unsigned)count;包含对象个数。-(id)objectAtIndex:(unsigned int)index;获取特定索引处的对象。

异常处理:

如果index大于数组对象个数:Terminating app due to uncaught exception 'NSRangeException' reason:'...',有许多捕获异常并处理的反复。

CF:Core Foundatin框架使用,与Cocoa框架一样,但是用C语言实现。CF中的对象和Cocoa对象直接是免费桥接的,可以互换使用。

切分数组:

Perl或者Python中习惯于将字符串切分成数组和将数组元素合并成字符串。NSArray也可以!

NSString *str = @"opp:abc:book:come";

NSString *chunks = [str componentsSeparatedByString:@":"];

str = [chunks componentsJoinedByString:@":)"];

这时候的str为"opp:)abc:)book:)come"

NSMutalbeArray:

+(idarrayWithCapacity:(unsigned)numltems; //预分配一个大小,不会将对象预写入数组,也不会限制数组大小。

-(void)addObject:(id)anObject; //在数组末尾添加对象

-(void)removeObjectAtIndex:(unsigned)index; //删除一个对象,主要索引从0开始,并且被删除对象后面的数组元素前移来填补空缺。

NSEnumerator枚举方法便利数组

-(NSEnumerator *)objectEnumerator;//向数组请求枚举器

-(id)nextObject; //向枚举器请求下一个对象,返回nil表示请求结束

NSEnumerator *enumerator;

id thingid;

enumerator = [array objectEnumerator];

while(thingid = [enumerator nextObject]){}

快速枚举。Objective-C 2.0中有快速枚举方法。

for(NSString *str in array) {NSLog(@"%@",str); } //循环体会 便利数组中每个元素。

NSDictionary是在给定关键字(比如一个字符串)下存储一个数值(对象),然后可以通过关键字来查找相应数值。

Tire *t1 = [Tire new];....Tire *t4 = [Tire new];

NSDictionary *tires = [NSDictionary dictionaryWithObjectsAndKeys:t1,@"f_l",t2,@"f_r",t3,@"b_l",t4,@"b_r",nil];

//接受对象和关键字 交替存储。nil终止

Tire *tire = [tires objectForKey:@"l_r"];

//返回一个id 这里是Tire对象,如果没有l_r关键字 返回nil。

NSMutableDictionary和NSMutableArray类似操作。

不要随意想创建NSString,NSArray,NSDictionary的子类!很多类是以类簇方式实现,它们是一群隐藏在通用接口下的与实现相关的类。创建NSString对象时,实际上获得的可能是NSLiteralString,NSCFString,NSSimpleCString对象。给类簇创建子类很麻烦,但是可以将NSString复合到我们自己的某个类或者使用类别vielai解决,而不用创建子类。

4.数值

NSArray,NSDictionary都不能存储任何基本类型的数据。我们可以用对象来封装基本数值,然后将该对象放入NSArray中。

NSNumber:

NSNumber *num;

num = [NSNumber numberWithInt/Char/Float/Bool:1];

[array addObject:num];

[dictionary setObject:num forKey :@"book"];

-(char)charValue; -(int)intValue;....-(NSString *) stringValue;用来解析NSNumber中封装的数据。

NSValue:

NSNumber是NSValue的子类。NSValue可以包装任何值。可以用来包装结构。

NSRect rect = NSMakeRect(1,1,20,20);

NSValue *value;

value = [NSValue valueWithBytes:&rect

objCType:@encode(NSRect)];

//(const void *)value想存储的变量的地址。c中&。@encode编译器可以接受数据类型名称并生成合适字符串。

[array addObject:value];

提取:

value=[array objectAtIndex:0];

[value getValue:&rect]; //使用了get,(void *)value 指针所指向的空间来存储该方法生成的数据。

对于结构:+(NSValue *)valueWithRect:(NSRect)rect; -(NSRect) rectValue;

NSNULL:

只有一个方法 +(NSNull *)null;

用在NSArray或者NSDictionary中表示这里什么都没有。因为nil被用了。

[contact setObject:[NSNull null]

forKey:@"haha"];

id hahaid;

hahaid = [contact objectForKey:@"haha"];

if(hahaid == [NSNull null]) {} //[NSNull null]返回的数值总是一样的,所以可以用==来值比较。