Foundation
Foundation框架在iOS开发中是必不可少的,是其它所有iOS框架的基础。这个框架中提供了很多常用的数据类型,如结构体、枚举、类等等。要想使用Foundation中的数据类型,包含它的主头文件即可
#import<Foundation/Foundation.h>,下面介绍几种常用的数据类型。
一、结构体
常用的结构体有NSRange、NSPoint(CGPoint)、NSSize(CGSize)、NSRect(CGRect)
1、NSRange
这个结构体是用来表示范围的,其内有两个变量,location和length,比如说有一个字符串”i love you”此时如果location =2,length = 4,就可以表示“love”这个字符串,再比如说一个数组,{10,2,30,50}
此时如果location = 1,length = 3,就可以表示{2,30,50},那这个结构体是怎么定义的呢?如下所示
NSRange r1 = {2,4};
NSRange r2 = {.location = 2,length = 4};
但上面两种定义方式很少用,第一种可读性差,第二种较长,一般我们用Foundation自带的函数来定义,如下
NSRange r3 = NSMakeRange(2,4);
说到这,还有一个结构体与这个很类似:
rangeOfString
它是用来查找某个字符串的范围,比如说
NSString *str = @”i love oc”;
NSRange range = [str rangeOfString:@”ve oc”];
NSLog(@”loc = %ld,length = %ld”,range.location,range.length)
这个结果打印出来后是loc = 4,length = 4
如果查找的时候找不到,length = 0,location = NSNotFound==-1
2、NSPoint(CGPoint)
这个结构体内有两个变量(X,Y)表示一个点,也就是一个坐标,定义方式如下
CGPoint p1 = NSMakePoint(10,10);
NSPoint p2 = CGPointMake(20,20); // 常用
3、NSSize(CGSize)
这个结构体内有两个变量(width,height),表示尺寸。定义方式如下
CGSize s1 = NSMakeSize(100,20);
NSSize s2 = CGSizeMake(20,20);
4、NSRect(CGRect)
这个结构体内有四个变量,一个点坐标(X,Y),一个尺寸(width,height),定义如下
CGRect r1 = CGRectMake(0,0,50,30);
二、字符串(NSString)
字符串属于类,它还有一个子类,NSMutableString,它们之间的区别等下再说,先说下NSString,首先说一下字符串的创建,它有以下几种方式
NSString *s1 = @”welfarezhang”;
NSString *s2 =[[NSString alloc] initWithString:@”Jack”];
NSString *s3 =[[NSString alloc] initWithFormat:@”age is %d”,19];
// C字符串-->OC字符串
NSString *s4 =[[NSString alloc] initWithUTF8String:”Jack”];
// OC字符串-->C字符串
char *cs =[s4 UTF8String];
NSString*s5=[[NSString alloc]initWithContentsOfFile:@”/Users/Desktop/”encoding:NSUTF8StringEncoding error:nil];
// URL:资源路径
// 格式 协议头://路径
// 网页资源 http://
// 本地资源 file://
NSString*s6=[[NSStringalloc]initWithContentsOfURL:file:///Users/apple/abc.txt encoding:NSUTF8String Encoding error:nil];
读取资源最万能的是用URL
上面介绍了六中字符串的创建,看上去都比较麻烦,这时候我们可以使用类方法来创建字符串,一般来说都会有一个类方法与对象方法配对。如下
[NSString stringWithFormat:@”welfarezhang”];
上面说的是字符串的创建,下面说下字符串的导出,如下所示
[@”welfarezhang”writeToFlie:@”/Users/my.txt”atomically:YES Encoding error:nil];
NSString *str =@”32323”;
NSURL *url =[NSURLfileURLPath:@”/Users/my.txt”];
[str writeToURL:url atomically:YES encoding:NSUTF8String Encoding error:nil];
这是字符串的导出,这些东西自己有个印象就好,看到这句代码知道什么意思即可,到后面慢慢就熟悉了。
前面说了有NSString 它还有一个子类,NSMutableString,下面说一下它们的区别。
NSString:它的字符串是不可变的,也就是说当它的字符串创建并赋值之后,就不能再添加或删除里面的内容
NSMutableString:它的字符串是可以改变的,字符串创建之后,是可以再往里面添加或删除内容的
下面举例说一下
NSMutableString *s1 = [NSMutableString stringWithFormat:@”age is 10”];
NSString *s2 = [NSString stringWithFormat:@”age is 10”];
在内存中如下图所示
拼接内容到S1后面
[s1 appendString:@”11 12”];
删除字符串中的“is”
// 获取is的范围
NSRange range =[s1 rangeOfString:@”is”];
// 删除is
[s1 deleteCharactersInRange:range];在内存中的表示如下图所示
在程序中这两个经常一起使用来删除某些内容。但NSString并没有这些指令,它有一个类似的指令是这样的
NSString *s3 =[s2 stringByAppendingString:@”11 12”];
它是复制了s2中的内容并添加了“11 12”并复制给了一个新的变量s3,但s2中的内容并没有改变,如下图所示
三、集合类
NSArray、NSSet、NSDictionary这三个称为集合类,它们都有对应的子类,用法与字符串和它的子类差不多,下面说一下它们的用法
1.NSArray
1>数组的创建
这是OC的数组,前面我们一直在用C语言的数组,但它有很多局限性,一个数组只能放一种类型的数据,OC只要是对象都可以存放,但它也有一个局限性,不能放非OC对象类型,比如int、struct,这并不影响我们对OC数组的使用,当需要放非OC对象时我们可以通过其它方式,它的创建如下
// 这个array永远是空数组(不可变)
NSArray *array = [NSArray array];
// nil是数组结束的标记
NSArray *array2 = [NSArray arrayWithObject:@”jack”,@”rose”,nil];
// 快速创建一个NSArray对象
NSArray *array =@[@”jack”,@”rose”,@”23456”];
与前面的相比更简洁,这也是编译器新特性
2>NSArray元素个数
我们可以通过数组名.count 来获取数组的元素个数,比如我们想获取上面array2数组的元素,
array2.count;
3>NSArray元素的访问
NSLog(@”%@”,[array2 objectAtIndex:1]);
此时打印出来的是”rose”我们也可以用前面所学的C访问数组的方式访问OC数组,如下
NSLog(@”%@”,array2[0]);
此时打印出来的是“jack”,通常我们采取后者来访问OC数组成员,这是编译器很特性,它会自动帮我们转换成前者的形式。
4>数组的遍历
前面的东西一说,我们很容易遍历一个OC数组。代码如下
Person *p = [[Person alloc] init];
NSArray *array = @[p,@"jack"];
for (int i = 0;i<array.count;i++)
{
NSLog(@"%@",array[i]);
}
还有一种快速遍历的方式如下
Person *p = [[Person alloc] init];
NSArray *array = @[p,@"jack"];
// id obj 代表数组的每一个元素
for(id obj in array)
{
NSUInteger i = [array indexOfObject : obj]
NSLog(@"%ld-%@",i,obj);
}
还有一种方式是通过Block方式来访问数组,如下
[array enumerateObjectsUsingBlock:
// *stop 是用来停止遍历的
^(id obj,NSUInteger idx,BOOL *stop)
{
NSLog(@"%ld-%@",idx,obj);
}
}
];
如果在上面的遍历中我们不想遍历整个数组,就让它停止遍历,我们可以通过*stop来实现。默认情况下*stop是NO,如果变成YES,它就会停止遍历,这就像我们循环结构中的break,如下
[array enumerateObjectsUsingBlock:
// *stop 是用来停止遍历的
^(id obj,NSUInteger idx,BOOL *stop)
{
NSLog(@"%ld-%@",idx,obj);
if(idx == 1)
{
// 如果有这句代码,程序就会在条件成立的时候停止遍历
*stop = YES;
}
}
];
上面的程序在索引为1时就会停止遍历。
与字符串类似,NSArray也有自己的子类,NSMutableArray,它们之间的区别与字符串一样,NSArray不可变,NSMutableArray可变
这里就不在详细说了。
2.NSSet
这个集合也可以存储很多东西,它与NSArray最大的区别是它是没有顺序的,它的定义如下
NSSet *s = [NSSet set];
NSSet *s2 = [NSSet setWithObject:@”jack”,@”rose”,nil];
因为它是无序的所以不能像数组那样访问元素,它有自己的一个方法
NSSet *s3 = [NSSet anyObject];
它是随机返回一个值。
下面说下NSSet与Array的对比
1.共同点
1>都是集合,都能存放多个OC对象
2>只能存放OC对象,不能存放非OC对象类型(基本数据类型:int、char。Float等,结构体,枚举)
3>本身都不可变,都有一个可变的子类。
2.不同点
NSArry有顺序,NSSet没有顺序
3.NSDictionary
NSDictionary的创建
key---> value
索引---> 文字内容
里面存储的东西都是键值对
NSDictionary*dict=[NSDictionarydictionaryWithObject:@”jack”forkey:@”name”];
[dict objectForKey:@”name”];
此时返回出来的是jack,这个NSDictionary也是不可变的,刚开始里面有什么内容,一直就是那些内容,下面的代码可以创建多个键值对
NSArray *keys = @[@“name”,@”address”];
NSArray *obj = @[@”JAKE”,@”beijing”];
NSDictionary *dict = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
id obj = [dict objectForKey:@”address”];
NSLog(@”%@”,obj);
此时打印出来的是“beijing”,也就是说key与obj是一一对应的,如果输入keys不存在,会打印出来nil,不会报错。如
id obj = [dict objectForKey:@”number”];
此时打印出来的就是nil。字典还有一种创建方式,这是编译器的新特性,与数组的快速创建相似,如下所示
NSDictionary *dict =@{@”name”:@”jack”,@“address”:@“beijing”};
前面是key,后面是object,可读性非常好,同时也省去了我们不少麻烦。以后写代码用这种方式,访问字典还有另一种方式,如下
id obj = dict[@”name”];有时我们想查看字典里面的个数,可以调用如下指令
Dict.count
它返回的是键值对的个数,不是key与object的总个数
与前面说讲的字符串与数组相似,字典也有子类,NSMutableDictionary,用法相似,一个可变,一个不可变,这里就不在多说。下面在说一下字典的遍历 如下
NSDictionary *dict = @{@”name”:@”jack”,@”qq”:@”837221314”};
NSArry *keys = [dict allkeys];
for(int i = 0;i<dict.count;i++)
{
NSString *key = keys[i];
NSString *object = dict[key];
}
这种遍历比较麻烦,所以一般不采用字典遍历
还有一点,字典也是无序的,可以有相同的object,但不能有相同的key。