首页 > 代码库 > Objective-C之成魔之路【15-Foundation框架】

Objective-C之成魔之路【15-Foundation框架】

郝萌主倾心贡献,尊重作者的劳动成果,请勿转载。

如果文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额随意,重在心意^_^ 

我要捐赠: 点击捐赠

Cocos2d-X源码下载:点我传送



概述
Mac OS X开发会使用 Cocoa框架,
它是一种支持应用程序提供丰富用户体验的框架, 
它实际上由: Foundation和Application Kit(AppKit)和 Core Data框架组成。 
iOS开发, 会使用 Cocoa Touch框架, 
它实际上由: Foundation、Core Data和UIKit框架组成。 
AppKit和UIKit框架都是与窗口 、 按钮、 列表等相关的类。
Foundation是Mac OS X和iOS应用程序开发的基础框架, 
它包括了一些基本的类, 如: 数字、 字符串、 数组、 字典等。

快速概要:

光标放在需要搜索的类、方法或变量上,按住Option键,同时单击鼠标,你会看到所选择内容的快速概要。

在面板的右上角注意到有两个图标:第一个是一本书,第二个是一个字符h。

单击那个书的图标,Xcode会查找选择的类、协议、定义或者方法的相关文档。

单击字符h的图标,将会显示包含选择项目定义的头文件。


MAC OS X在线参考库,地址是点击打开链接。


要使用Foundation框架中的类,要先引用头文件:

#import <Foundation/Foundation.h>

实际上,因为Foundation.h文件导入Foundation所有的头文件,所以不必担心是否导入正确的头文件。

但使用这条语句会明显增加程序的编译时间。

所以,一般import用到的头文件。不要用太大的import。


基本数据类型:

int、 char、 float和double都不是类, 

具有方法、 成员变量和属性, 以及面向对象的特征。 

为了实现“一切都是对象” 的承诺, 

因此在Foundation框架中使用NSNumber类来封装这些数字类型。 

这样数字就具有了面向对象的基本特征了。


也就是说:如果需要存储基本数据类型(包括char数据类型),可以使用NSNumber类,

它会依据这些数据的类型创建对象。

对于每种基本数据类型,类方法都能为它创建一个NSNumber对象,并设置为指定的值。


NSNumber类构造函数
采用 + numberWithInt: 等“+ number” 开头的类级构造方法, 可以从基本数据类型构建NSNumber对象。 
而使用 –intValue方法可以从NSNumber对象获得基本数据类型。 

这些方法以numberWith开头,紧接着数据的类型,如:numberWithLong:
NSNumber *intNumber= [NSNumber numberWithInteger:80];
NSNumber *floatNumber = [NSNumber numberWithFloat:
80.00];
int myint = [intNumber intValue];
float myfloat = [floatNumber floatValue];

注意,方法numberWithInt:和numberWithInteger:使用有些差别,遵循以下一些规则:

1)如果使用numberWithInt:方法创建一个整型数,需要使用intValue获取它的值,使用%i作为格式化字符串显示它的值。

2)如果使用numberWithInteger:方法创建一个整型数,需要使用integerValue获取它的值,也可以转换成long显示或使用stringWithFormat:将它格式化为字符串。使用%li作为格式化字符串。


比较两个NSNumber对象大小
可以转化成为基本数据类型比较, 当然可以使用 NSNumber的方法比较, 
这就是对象的优势了, 与比较相关方法有:
isEqualToNumber: 和compare: 。 
isEqualToNumber: 只是比较是否相对, compare: 可以比较大小。
if ([intNumber isEqualToNumber: floatNumber] == YES) {
NSLog(@"相等");
} else {
NSLog(@"不相等");
}
if ([intNumber compare: myNumber] ==
NSOrderedAscending) {
NSLog(@"第一个数小于第二个数");
}
NSOrderedAscending是枚举类型NSComparisonResult的其中成员, 代表第一个数小于第二个数, 
此外还有NSOrderedSame成员代表第一个数等于第二个数, 
NSOrderedDescending成员代表第一个数大于第二个数。

字符串类
在Foundation框架中字符串类有两种: 
NSString不可变字符串类和NSMutableString可变字符串类。 
NSString是定义固定大小的字符串, 
NSMutableString是可对字符串做追加、删除、 修改、 插入和拼接等操作而不会产生新的对象。

NSString类

NSSTring的类,用于处理字符串对象。然而C样式的字符串由char字符组成,NSString对象由unichar字符组成。

要使用Objective-C语言创建一个常量字符串对象,需要在字符串开头放置一个@字符。

创建字符串对象时,会创建一个内容不可更改的对象,这称为不可变对象。

需要制定一个范围确定子字符串,使用特殊的数据类型NSRange类创建对象。

实际上,它是结构的typedef定义,包含location和length两个成员。

如果没有找到这个字符串,则返回范围的location成员被设置为NSNotFound。


stringWithString:类级构造方法创建NSString对象,NSString构造方法还有很多;
length,返回Unicode字符的长度;
stringByAppendingString:实现了字符串的拼接,这个方法会产生下一新的对象;
isEqualToString:比较两个字符串是否相等;
compare: 比较两个字符串大小;
substringToIndex:可以获得字符串的前x个字符串;
substringFromIndex:可以截取x索引位置到尾部字符串;
rangeOfString:字符串查找;

下面来看一段示例代码:
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	NSString *str1 = @"aBcDeFgHiJk";
	NSString *str2 = @"12345";
	NSString *res;
	NSComparisonResult compareResult;
	NSRange subRange;
	
	//字符个数
	NSLog(@"字符串str1长度: %i",[str1 length]);
	//拷贝字符串到res
	res = [NSString stringWithString: str1];
	NSLog(@"拷贝: %@", res);
	//拷贝字符串到str1尾部
	str2 = [str1 stringByAppendingString: str2];
	NSLog(@"连接字符串: %@", str2);
	
	//测试字符串相等
	if ([str1 isEqualToString: res] == YES) {
		NSLog(@"str1 == res");
	} else {
		NSLog(@"str1 != res");
	}
	//测试字符串 < > == 
	compareResult = [str1 compare: str2];
	if (compareResult == NSOrderedAscending) {
		NSLog(@ "str1 < str2");
	} else if (compareResult == NSOrderedSame) {
		NSLog(@ "str1 == str2");
	} else {
		NSLog(@ "str1 > str2");
	}
	res = [str1 uppercaseString];
	NSLog(@"大写字符串:%@", res);
	res = [str1 lowercaseString];
	NSLog(@"小写字符串:%@", res);
	NSLog(@"原始字符串: %@", str1);
	
	//获得前三个数
	res = [str1 substringToIndex: 3];
	NSLog(@"字符串str1的前三个字符: %@",res);
	res = [str1 substringFromIndex: 4];
	NSLog(@"截取字符串,从第索引4到尾部: %@",res);
	
	res = [[str1 substringFromIndex: 3] substringToIndex: 2];
	NSLog(@"截取字符串,从第索引3到5: %@",res);
	
	//字符串查找	
	subRange = [str2 rangeOfString: @"34"];
	
	if (subRange.location == NSNotFound) {
		NSLog(@"字符串没有找到");
	} else {
		NSLog (@"找到的字符串索引 %i 长度是 %i", 
			   subRange.location, subRange.length);
	}
	
	
	[pool drain];	
	return 0;
	
}
我们解释一下主要代码:
str2 = [str1 stringByAppendingString: str2] 语句是将两个字符串对象拼接在一起, 
由于NSString是不可变字符串类, 这会产生一个新的对象。 
subRange = [str2 rangeOfString: @"34"] 中的rangeOfString: 方法会返回一个NSRange结构体, 
它的location成员是找到的字符串的索引 , 它的length成员是找到的字符串的长度。

NSMutableString 类

NSMutableString类可以用来创建可以更改字符的字符串对象。

注意,如果替换字符串中还包括搜索字符串(如:使用字符串“ax”替换字符串“a”),

那么将会陷入无限循环。

其实,这个是和它的实现原理有关系,一般这种替换使用的方法使用了递归调用。


stringWithString: 类级构造方法创建NSString对象,NSMutableString构造方法还有很多; 
insertString: 插入字符串, 不会创建新的对象; 
appendString: 追加字符串, 不会创建新的对象; 
deleteCharactersInRange: 在一个范围内删除字符串, 不会创建新的对象; 
replaceCharactersInRange: withString: 替换字符串, 不会创建新的对象;
再看断示例代码:
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	NSString *str1 = @"Objective C";
	NSString *search,*replace;
	NSMutableString *mstr;
	NSRange substr;
	
	//从不可变的字符创建可变字符串对象
	mstr = [NSMutableString stringWithString: str1];
	NSLog(@" %@", mstr);
	
	//插入字符串
	[mstr insertString: @ " Java" atIndex: 9];
	NSLog(@" %@", mstr);
	//具有连接效果的插入字符串
	[mstr insertString: @ " and C++"atIndex: [mstr length]];
	NSLog(@" %@", mstr);
	//字符串连接方法
	[mstr appendString: @ " and C"];
	NSLog(@" %@", mstr);	
	//使用NSRange删除字符串
	[mstr deleteCharactersInRange:NSMakeRange(16, 13)];
	NSLog(@" %@", mstr);	
	//查找字符串位置
	substr = [mstr rangeOfString: @ "string B and"];
	if (substr.location != NSNotFound) {
		[mstr deleteCharactersInRange: substr];
		NSLog(@" %@", mstr);
	}
	//直接设置可变字符串
	[mstr setString: @ "This is string A "];
	NSLog(@" %@", mstr);
	
	[mstr replaceCharactersInRange: NSMakeRange(8, 8)
						withString: @ "a mutable string "];
	NSLog(@" %@", mstr);
	//查找和替换
	search = @"This is ";
	replace = @"An example of ";
	
	substr = [mstr rangeOfString:search];
	
	if (substr.location != NSNotFound) {
		[mstr replaceCharactersInRange:substr withString: replace];
		NSLog(@" %@", mstr);
	}
	//查找和替换所有的情况
	search = @"a";
	replace = @"X";
	substr = [mstr rangeOfString: search];
	
	while (substr.location != NSNotFound) {
		[mstr replaceCharactersInRange:substr withString: replace];
		substr = [mstr rangeOfString: search];
	}
	NSLog(@" %@", mstr);
	
	
	
    [pool drain];
    
	return 0;
}
我们解释一下主要代码:
语句[mstr deleteCharactersInRange:NSMakeRange(16, 13)] 是删除指定范围的字符串, 
函数NSMakeRange 是创建NSRange结构体, 其中第一个参数是位置, 第二个参数是长度, 
语句[mstr replaceCharactersInRange: NSMakeRange(8, 8) withString:@“a mutable string ”] 替换指定访问的字符串。 
[mstr deleteCharactersInRange: substr] 语句是删除指定范围的字符串。

数组类
在Foundation框架中数组被封装成为类

数组对象:是Foundation数组是有序的对象集合。

数组有两种

NSArray不可变数组类和NSMutableArray可变数组类


注意,需要标记参数数组的结束,将这个数组的最后一个值定为nil,它实际上并不会存储在数组中。

数组中的元素是由它们的索引数确定的。与NSString对象类似,索引从0开始。

可以通过NSLog格式化字符串%@显示整个数组。


NSArray类
NSArray有很多方法, 下面是总结常用的方法: 
count: 返回当前数组的长度; 
objectAtIndex: 按照索引返回数组中的元素; 
containsObject: 是否包含某一元素; 
arrayWithObjects: 类级构造方法; 
initWithObjects: 实例构造方法
NSArray的实例代码如下:
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSArray *weeksNames = [NSArray arrayWithObjects: 
						   @"星期一",@"星期二",@"星期三",@"星期四"
						   ,@"星期五",@"星期六",@"星期日",nil];
    NSLog(@"星期名字");
    NSLog(@"====   ====");
    int i;
    for (i=0; i < [weeksNames count];i++) {
    	NSLog(@"%2i     %@ ", i+1, [weeksNames objectAtIndex: i]);    	
    }
	
	
    [pool drain];
    return 0;
}
arrayWithObjects可以用来创建使用一列对象作为元素的数组。 
在这种情况下, 按顺序列出对象并使用逗号隔开。 
使用这个方法必须在列表的最后指定一个结束标志nil 。 
count可以获得数组的长度。 数组的下标是从0开始的

NSMutableArray类
NSMutableArray是NSArray的子类, NSMutableArray有很多方法, 
下面是总结常用的方法: 
addObject: 在数组的尾部追加一个元素; 
insertObject: 在数组的添加一个元素; 
atIndex: 按照索引插入一个元素; 
removeObjectAtIndex: 移除特定索引的元素; 
removeObject: 移除特定元素; 
initWithCapacity: 实例构造方法

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
   
	NSMutableArray *weeksNames = [[NSMutableArray alloc] initWithCapacity: 3];
    [weeksNames addObject: @"星期一"];   
	[weeksNames addObject: @"星期二"];
    [weeksNames addObject: @"星期三"];   
	[weeksNames addObject: @"星期四"];
    [weeksNames addObject: @"星期五"];    
	[weeksNames addObject: @"星期六"];
    [weeksNames addObject: @"星期日"];  
	
	NSLog(@"星期名字");
    NSLog(@"====   ====");
	
    int i;
    for (i=0; i < [weeksNames count];i++) 
    	NSLog(@"%2i     %@ ", i+1, [weeksNames objectAtIndex: i]); 
	
	[weeksNames release];

    return 0;
	
}
[[NSMutableArray alloc] initWithCapacity: 3] , 可以初始化可变数组并分配3个初始单元, 
如果超过了容量会自动追加的。 
addObject方法可以向数组中添加元素

NSValue:

数组这样的Foundation集合只能存储对象,不能存储像int这样的基本数据类型。

NSValue类正好可以将结构转化为对象,并且把它存储在集合中。

这种将结构化转为对象的方式,简称为包装(wrapping),

逆向的处理是从对象中解出基本类型,简称展开(unwrapping)。


字典类
字典集合, 它是由“键-值”对构成的集合。 
键集合不能重复,也就是说字典中的键必须是单值的;

值集合没有特殊要求。 
键和值集合中的元素通常是字符串,但也可以是任何对象, 但是不能是nil。 

词典可以使固定的,也可以是可变的。

可变词典中的记录可以动态添加和删除。

和数组对象不一样,词典对象是无序的。

这个字典类与java中的HashMap很相似,也是key-value的格式。

举例如下:
字典类数据结构模型, 
图所示的“学生与学号”集合;

与数组类一样, 字典类也分为NSDictionary不可变字典和NSMutableDictionary可变字典。 

NSDictionary类
NSDictionary有很多方法, 下面是总结常用的方法: 
count字典集合的长度; 
objectForKey: 通过键获得值对象; 
allKeys: 返回所有键集合; 
arrayWithObjects: 类级构造方法; 
initWithObjects: 实例构造方法; 
initWithObjects:forKeys: 实例构造方法; 
initWithObjectsAndKeys: 实例构造方法; 
initWithContentsOfFile: 从属性文件中创建对象;
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
	
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	NSArray * keys = [@"one two three four five" componentsSeparatedByString:@" "];
	NSArray * values = [@"alpha bravo charlie delta echo" componentsSeparatedByString:@" "]; 
	NSDictionary * dict = [[NSDictionary alloc] initWithObjects:values forKeys:keys];
	
	NSLog(@"%@", [dict description]);
	
	[dict release];
	
    [pool drain];
    return 0;
}
NSArray * keys = [@“one two three four five”componentsSeparatedByString:@“ ”] 语句是将一个字符
串按照空格分割返回NSArray对象, 同理获得values对象,
然后使用 NSDictionary * dict = [[NSDictionary alloc] initWithObjects:values forKeys:keys] 语句
把keys和values放入到不可变字典对象dict中。

NSMutableDictionary类
NSMutableDictionary 是NSDictionary的子类,
NSMutableDictionary有很多方法, 下面是总结常用的方法: 
setObject: forKey: 通过键和值; 
removeObjectForKey: 按照键移除值; 
writeToFile: atomically: 把对象写入到文件中;
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	NSMutableDictionary *mutable = [[NSMutableDictionary alloc] init];
    
    // add objects
    [mutable setObject: @"Tom" forKey: @"tom@jones.com"];
    [mutable setObject: @"Bob" forKey: @"bob@dole.com" ];
	
	NSLog(@"%@", [mutable description]);
	
	[mutable release];
	
    [pool drain];
    return 0;
}
NSMutableDictionary *mutable = [[NSMutableDictionary alloc] init] 是采用默认的init构造方法创建
NSMutableDictionary对象mutable。 
[mutable setObject:@"Tom" forKey: @"tom@jones.com"] 语句是按照键tom@jones.com添加Tom对象。

集合对象:

set是一组单值对象集合,它可以是变的或不可以变的。

操作包括:搜索、添加、删除集合中的成员(仅用于可变集合),比较两个集合,计算两个集合的交集和并集等。

这些集合对象包括:NSSet、NSMutableSet、NSIndexSet和NSCountedSet等。

注意,NSIndexSet没有可变版本。

Objective-C之成魔之路【15-Foundation框架】