⑩--Foundation框架基础
来源:互联网 发布:天猫淘宝棉拖鞋 编辑:程序博客网 时间:2024/05/01 00:09
OC的基本语法告一段落了,今天开始学习Foundation框架。
1.Foundation框架介绍
之前已经介绍了什么是框架以及如何使用一个框架。Foundation框架是其他所有iios框架的基础
Foundation框架包含了很多开发中常用的数据类型:
√结构体
√枚举
√类
要想使用Foundation框架中的数据类型,包含它的主头文件即可
#import <Foundation/Foundation.h>
下面介绍Foundation框架中的一些常见的基本用法。
2.常用结构体--NSRange、NSPoint/CGPoint、NSSize/CGSize、NSRect\CGRect
①NSRange是表示范围的结构体,它在Foundation中的定义如下:
typedef struct _NSRange { NSUInteger location; NSUInteger length;} NSRange;
可以看出NSRange有两个变量组成:
一个是代表位置的location;
一个是代表长度的length。
这两个变量的类型都是NSUInteger类型,对于NSUInteger其实就是无符号的长整型:
#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64typedef long NSInteger;typedef unsigned long NSUInteger;#elsetypedef int NSInteger;typedef unsigned int NSUInteger;#endif
NSRange有如下的用途:
例如@"i love oc"这个字符串中,有个子串@"love",他在@"i love oc"中的范围用NSRange表示就是:location为2,length为4.
如何声明并初始化一个NSRange:按照C语言中对结构体初始化的方法:
NSRange r1 = {2, 4}; // 不用NSRange r2= {.location = 2, .length = 4}; // 不用上面的两种初始化方法在官方是不推荐的,它推荐使用下面的方式进行初始化:
NSRange r3 = NSMakeRange(2, 4); // 掌握
查找某个字符串在str中的范围
NSString *str = @"i love oc";// 查找某个字符串在str中的范围NSRange range1 = [str rangeOfString:@"love"];NSLog(@"loc = %ld, length = %ld", range1.location, range1.length); // ->loc = 2, length = 4
如果找不到,length = 0,location=NSNotFound==-1%d
NSString *str = @"i love oc";// 查找某个字符串在str中的范围// 如果找不到,length = 0,location=NSNotFound==-1%dNSRange range2 = [str rangeOfString:@"java"];NSLog(@"loc = %ld, length = %ld", range2.location, range2.length); // ->loc = NSNotFound ,length = 0
(注:实际上上面loc的值是9223372036854775807 它其实表示的是长整型数值的-1)
②NSPoint\CGPoint、NSSize/CGSize、NSRect\CGRect
顾名思义,我们可以猜测NSPoint表示的是点,实际上NSPoint的定义为:
typedef CGPoint NSPoint;
而CGPoint的定义为:
struct CGPoint { CGFloat x; CGFloat y;};typedef struct CGPoint CGPoint;显然CGPoint里面定义了表示点的两个坐标值:x和y。它们都是CGFloat类型的数据:
# define CGFLOAT_TYPE doubletypedef CGFLOAT_TYPE CGFloat;
可见CGFloat其实就是double类型。
按照刚才初始化一个NSRange类型的数据的方式初始化一个NSPoint:
CGPoint p1 = NSMakePoint(10, 10);
但实际上最常用的是另一种方法:
NSPoint p2 = CGPointMake(10, 10); // 最常用
再看NSSize/CGSize,它们在Foundation中的定义是这样的:
typedef CGSize NSSize;
struct CGSize { CGFloat width; CGFloat height;};typedef struct CGSize CGSize;
同样地,也有初始化它们的类似方法:
NSSize s1 = NSMakeSize(100, 50);NSSize s2 = CGSizeMake(100, 50);
再看NSRect\CGRect,它们的定义如下:
typedef CGRect NSRect;struct CGRect { CGPoint origin; CGSize size;};typedef struct CGRect CGRect;
NSRect\CGRect常用来表示UI元素在屏幕中的区域,包括CGPoint类型的原点origin,和CGSize类型的size。
初始化它们有如下方法:
NSRect r1 = CGRectMake(0, 0, 100, 50); //方式1CGRect r2 = {{0, 0}, {100, 90}}; // 方式2CGPoint p1 = NSMakePoint(10, 10);NSSize s1 = NSMakeSize(100, 50);CGRect r3 = {p1, s1}; // 方式3也可以这样初始化:
CGRect r4 = {CGPointZero, CGSizeMake(100, 90)};
其中CGPointZero == CGPoint(0, 0);表示(0, 0)点。
在Foundation中拥有将结构体直接转为字符串的全局方法:
NSRect r1 = CGRectMake(0, 0, 100, 50);NSString *str = NSStringFromRect(r1); // 将结构体转为字符串打印NSLog(@"%@", str);输出的结果为:
2014-12-28 10:52:24.514 01-结构体[615:303] {{0, 0}, {100, 50}}NSPoint\CGPoint、NSSize/CGSize、NSRect\CGRect有就几个在开发中常用的函数:
// 使用这些函数的前提是添加CoreGraphic框架// 比较两个点是否相同(x, y)BOOL b = CGPointEqualToPoint(CGPointMake(10, 10), CGPointMake(10, 10));BOOL b1 = CGRectContainsPoint(CGRectMake(0, 0, 100, 50), CGPointMake(2, 3));NSLog(@"%d", b1);
输出结果为:
2014-12-28 10:55:06.695 01-结构体[626:303] 1
3.NSString类和NSMutableString类
①NSString类
NSString类也就是OC中的字符串类,很多用法已经不陌生了。
创建一个NSString对象的方法:
NSString *s1 = @"12212";//NSString *s2 = [[NSString alloc] initWithString:@"df"]; // 太繁琐// 3.创建格式化的字符串NSString *s3 = [[NSString alloc] initWithFormat:@"age is %d", 10]; // 4.C语言字符串----> OC字符串NSString *s4 = [[NSString alloc] initWithUTF8String:"C语言字符串"];
上面可以看到一中C语言字符串转为OC字符串的方法,OC字符串也可以转为C语言字符串:
// OC字符串------->c语言字符串const char *cs = [s4 UTF8String];
还有更强大的用法,从一个文件中获取字符串:
// NSUTF8StringEncoding 用到中文就可以用这种编码NSString *s5 = [[NSString alloc] initWithContentsOfFile:@"/Users/Mike/Desktop/note/目标.txt" encoding:NSUTF8StringEncoding error:nil];
还可以从一个URL中获取字符串:
为此我们先定义一个URL:
NSURL *url = [[NSURL alloc] initWithString:@"file:///Users/Mike/Desktop/note/目标.txt"]; // 创建失败
但实际上,像上面这样带中文的URL是不会创建成功的,解决的方案有三种:
方案一:如果是文件,使用URL类的fileURLWithPath函数:
NSURL *url = [NSURL fileURLWithPath:@"/Users/Mike/Desktop/note/目标.txt"];// 可以*******
方案二:将路径中的中文改为这个中文的Unicode编码:
NSURL *url = [[NSURL alloc] initWithString:@"http://mike.qiniudn.com/%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E6%A0%91%E5%BD%A2%E5%9B%BE2.html"]; ///可以****
方案三:使用NSString的函数将中文转为Unicode编码再操作:
NSString *sUrl = [@"file:///Users/Mike/Desktop/note/目标.txt" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];NSURL *url = [[NSURL alloc] initWithString:sUrl];要注意URL路径的格式规则:
协议头://路径
如
"file:///Users/Mike/Desktop/note/目标.txt"
"http://www.baidu.com/index.php"
注意****************
以上方法可以直接使用类方法 不用每次都alloc
一般都会有个类方法跟对象方法配对
****************
例如:[[NSString alloc] initWithFormat:@"age is %d", 10];
可以直接写成:
[NSString stringWithFormat:@"age is %d", 10];
而对于
[[NSURL alloc] initWithString:sUrl];
直接写成:
[NSURL URLWithString:sUrl];
也就是将“ alloc+initWith”改成“类With”。这是通用的做法。
字符串还有一些写入方法,如将字符串写到文件中:
[@"jack" writeToFile:@"file:///Users/Mike/Desktop/note/a.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];当然还有writeToURL等方法。
②NSMutableString
NSMutableString是可变的字符串,它继承自NSString.但是又针对"可变"扩展了很多方法。
NSMutableString常用的方法有,拼接字符串到当前字符串后面:
NSMutableString *s1 = [NSMutableString stringWithFormat:@"age is 10"]; [s1 appendFormat:@" 11 12"]; // 尾部添加NSLog(@"s1 = %@", s1); // s1 = age is 10 11 12
删除字符串中的字符:
</pre></p><p><span style="font-size:14px;"></span><pre name="code" class="objc">NSMutableString *s1 = [NSMutableString stringWithFormat:@"age is 10"];[s1 deleteCharactersInRange:NSMakeRange(4, 2)]; //删除isNSLog(@"s1 = %@", s1); // s1 = age 10
上面的操作的需要传入字符的范围,比较麻烦,可以使用如下方法简化:
NSMutableString *s1 = [NSMutableString stringWithFormat:@"age is 10"];[s1 deleteCharactersInRange:[s1 rangeOfString:@"is"]]; //删除isNSLog(@"s1 = %@", s1); // s1 = age 10
对于NSString也可以实现上面的字符串拼接功能,但是NSString不可变,必须要用新的值就接受拼接后的字符串:
NSString *s2 = [NSString stringWithFormat:@"age is 10"]; NSString *s3 = [s2 stringByAppendingString:@" 11 12"]; // s2不变 新的字符串用s3接收NSLog(@"s2 = %@, s3 = %@", s2, s3); // s2 = age is 10, s3 = age is 10 11 12
这就体现出了NSString和NSMutableString的区别:不可变和可变。
4.NSArray和NSMutableArray
类似于Java的集合类,OC中有NSArray、NSSet、NSDictionary.
①NSArray是数组类可以存放一些数据,类型是可以不同的,但是存放在NSArray中是有序的
为什么要引入NSArray数组类,先看C语言中数组的局限性:
√C语言的数组不够灵活,只能存放一种数据类型;
√C语言的数组面向过程,几乎没有什么可以操作数组的方法,且操作起来非常困难。
而NSArray解决了上面的问题,但也有一定的要求:
√OC数组只能存放oc对象不能存放非OC对象,如int、struct、enum等等;
√OC数组不能存放空值(数组以nil为结束)。
创建一个数组:NSArray *array = [NSArray array]; //但是这个数组永远是空数组,因为NSArray不可变,创建时没有指定元素,所以长度为0但是又不能添加元素。
应当这样创建:
NSArray *array2 = [NSArray arrayWithObjects:@"jack", nil];并且以nil作为结束。
数组类的常用操作:获取数组元素的个数:
NSLog(@"%ld", array3.count);
访问数组的元素(按索引):
NSLog(@"%@", [array3 objectAtIndex:1]);
这种写法有种简化:
NSLog(@"%@", array3[0]); // 编译器特性这是种编译器特性,实际上会讲array3[0]转换为 [array3objectAtIndex:0];
还有一种针对NSArray的编译器特性,用于快速创建数组:
NSArray *array4 = @[@"jack", @"rose"];// 编译器特性 实际使用了arrayWithObjects这时候不能再加上结束标识nil,否则报错。
若想对数组进行遍历操作:可用的方法有很多种:
方法一:
NSArray *array = @[p, @"rose", @"jack"];// 方法1for (int i = 0; i < array.count; i++){ NSLog(@"%@", array[i]);}
// 方法2 for (id obj in array) // 快速遍历数组元素{ NSUInteger i = [array indexOfObject:obj]; // 找出obj元素在数组中的位置 NSLog(@"%ld----%@", i, obj);}
// 方法3// 没遍历到一个元素,就会调用一次block// 并且当前元素和索引位置当做参数传给block[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSLog(@"%ld---%@", idx, obj);}];
其内部相当于执行了下面的代码:
void ^(myblock)(id, NSUInteger, BOOL *) = ^(id obj, NSUInteger idx, BOOL *stop){ NSLog(@"%ld - %@", idx, obj);};for (int i = 0; i<array.count; i++){ // 用来标记是否需要停止遍历 BOOL isStop = NO; // 取出元素 id obj = array[i]; myblock(obj, i, &isStop); if (isStop) { break; }}
②NSMutableArray
NSMutableArray是可变的数组,它继承自NSArray。
NSMutableArray常用的操作有:
创建一个可变数组:要以nil结束
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"rose", @"jim", nil];
向数组中添加元素:
NSMutableArray *array = [NSMutableArray array];// 添加元素[array addObject:[[Person alloc] init]]; [array addObject:@"jack"];注意不能添加nil值的元素,因为nil是数组结束的标识。
[array addObject:nil]; // 错误写法
// 删除指定的对象[array removeObject:@"jack"];
按照索引删除元素:
[array removeObjectAtIndex:0];
// 删除所有的元素[array removeAllObjects];
注意:@[]只创建不可变数组 ,例如:
NSMutableArray *array = @[@"jack", @"rose"];当这一句执行时编译器值发生了警告:因为根据编译器特性@[@"jack",@"rose"];会转换成代码
[NSArrayarrayWithObjects:@"jack",@"rose",nil]; 这样赋值=的右边产生了一个NSArray对象,因此会产生类型不匹配的警告:
Incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'
若要继续添加下面这句:
[array addObject:@"jim"];就会引发错误:
[__NSArrayI addObject:]: unrecognized selector sent to instance
因为array本质上是一个NSArray而不是NSMutableArray,他不存在addObject方法。5.NSSet和NSMutableSet
①NSSet
NSSet也是一种集合类,它与NSArray最大的区别就是:
NSArray中的元素是有顺序的,因此NSArray中有索引的概念
NSSet中的元素是没有顺序的,就像数学中的集合Set具有无序性。
创建一个NSSet:
NSSet *s = [NSSet set]; // 永远为空的NSSet NSSet *s2 = [NSSet setWithObjects:@"jack",@"rose", @"jack2",@"jack3",nil];
取出一个元素:
// 随机拿出一个元素NSString *str = [s2 anyObject]; NSLog(@"%@", str);
②NSMutableSet
可变的Set,常用操作:
添加元素:
// 添加元素[s addObject:@"hack"];
删除元素
// 删除元素[s removeObject:(id)];
6.NSDictionary和NSMutableDictionary
①NSDictionary常被成为字典,相当于Java中HashMap,以键值对的形式存放数据,在开发中有非常对的使用。
创建一个NSDictionary对象
方式一:
添加一个键值对key:@"name",value:@"jack"
// 创建方式1NSDictionary *dict = [NSDictionary dictionaryWithObject:@"jack" forKey:@"name"];方式二:
有多个键值对时,可以用两个数组分别存放keys和values,利用方法
dictionaryWithObjects: forKeys:
// 创建方式2NSArray *keys = @[@"name", @"address"];NSArray *objs = @[@"jack", @"北京"];NSDictionary *dict = [NSDictionary dictionaryWithObjects:objs forKeys:keys];
方式三:
采用一个值value一个键key的方式赋值
// 创建方式3NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"jack", @"name", @"北京", @"address", @"123456", @"QQ", nil]; // 注意添加结束标识nil
// 编译器特性*************NSDictionary *dict = @{@"name":@"jack", @"address":@"北京"};
取出一个元素:
id obj = [dict objectForKey:@"name"]; NSLog(@"%@", obj); // jack
利用编译器特性,取出元素:
// 编译器特性**************obj = dict[@"address"]; NSLog(@"%@", obj); // 北京
②NSMutableDictionary
创建一个NSMutableDictionary:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
添加键值对:setObject方法
// 添加键值对[dict setObject:@"jack" forKey:@"name"];[dict setObject:@"北京" forKey:@"address"];
注意:给存在的key赋值,旧值被覆盖
// 给相同的key赋值时 旧值会覆盖[dict setObject:@"rose" forKey:@"name"];此时的name为rose;
移除键值对:根据key来移除
[dict removeObjectsForKeys:@"name"];
数组和字典的打印:
NSLog(@"%@", @[@"jack",@"rose"]); // 数组NSLog(@"%@",@{@"name":@"jack", @"address":@"北京"}); //字典
输出的结果是:
( jack, rose){ address = "\U5317\U4eac"; name = jack;}
与NSArray类似下面的,写法也是错误的:
NSMutableDictionary *dict = @{@"name":@"jack"}; [dict setObject:@"rose" forKey:@"name"];
NSDictionary 遍历
方法一:比较繁琐,依次取出key和valueNSDictionary *dict = @{@"name":@"jack", @"address":@"北京", @"qq":@"123456"}; // 方法1NSArray *keys = [dict allKeys];for (int i = 0; i < dict.count; i++){ id key = keys[i]; id obj = dict[key]; NSLog(@"%@ = %@", key, obj);}
方法二:利用block
// 方法2 用block非常方便[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { NSLog(@"%@ = %@", key, obj);}];
对集合的总结:
集合:
1.NSArray\NSMutableArray
*有序
*快速创建(不可变):@[obj1, obj2, obj3];
*快速访问元素:数组名[i]
2.NSSet\NSMutableSet
*无序
*无快速创建的方法
3.NSDictionary\NSMutableDictionary
*无序
*快速创建(不可变):@{key1;value1, key2:value2};
*快速访问元素:字典名[key];
7.NSNumber和NSValue
在前面的集合操作中,我们可以看到NSArray、NSSet和NSDictionary都只能存放OC的对象数据,然而对于基本数据类型char、int、float、double、enum和结构体struct都无法存放。NSNumber和NSValue就是用来解决这一问题的,使用NSNumber和NSValue来包装这些类型,可以让它们转换为对象类型的数据。
①NSNumber
将BOOL、char、int、float、double、NSInteger类型的数据包装成NSNumber类型的对象
NSNumber *b = [NSNumber numberWithBool:YES];NSNumber *c = [NSNumber numberWithChar:'A'];NSNumber *i = [NSNumber numberWithInt:10];NSNumber *f = [NSNumber numberWithFloat:0.1f];NSNumber *d = [NSNumber numberWithDouble:6.345];NSNumber *integer = [NSNumber numberWithInteger:1056];***********************************************注意
NSInteger不是对象类型,不要看到NS开头就以为是对象类型,他可能是结构体、枚举、常量等,NSInteger的定义如下:
#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64typedef long NSInteger;typedef unsigned long NSUInteger;#elsetypedef int NSInteger;typedef unsigned int NSUInteger;#endif可以看到在64位的编译器中NSInteger就是long,在32位的编译器中就是int
************************************************
不过每次都使用numberWith方法未免过于繁琐:利用编译器特性像下面这样包装即可:
NSNumber *b = @YES; // BOOL类型NSNumber *c = @'A'; // char类型 注意和字符串的区别NSNumber *i = @10; // int类型NSNumber *f = @0.1f; // float类型NSNumber *d = @6.345; // double类型NSNumber *integer = @1056; // NSInteger类型不仅仅如此,还可以这样包装数据:
int a = 10;NSNumber *na = @(a);这样的话,用了这么多天的NSLog();函数中的%d,%f什么的格式符都可以换成%@了(窃喜~~),多么强大的编译器特性。
可以用包装好的数据测试一下了:
NSNumber *num = [NSNumber numberWithInt:10]; // 或者使用NSNumber *num = @10;NSDictionary *dict = @{ @"name" : @"jack", @"age" : num };上面的代码现在一点错误也没有了,但是此时若用dict[@"age"];取出的是NSNumber类型,如何将它再转为基本数据类型呢?
方法是这样的:
NSNumber *num2 = dict[@"age"];int age = [num2 intValue]; NSLog(@"age = %d", age); // age = 10类似的,对于其他类型也可以采用相应的方法:类型Value。
需要注意的是NSString类型也有类似的方法:
[@"10" intValue]; // 10NSNumber不仅返回基本数据类型,还可以返回NSString类型的数据:
NSNumber *num2 = dict[@"age"];NSString *age = [num2 stringValue]; NSLog(@"age = %@", age); // age = 10
对NSNumber类型的分析:
NSNumber之所以能包装数据,是因为继承了NSValue ,
NSNumber只能包装数字类型,若要包装结构体就得使用NSValue。
使用NSValue将结构体包装成NSValue类型的OC对象:
// 将结构体包装成OC对象CGPoint p = CGPointMake(10, 10);// 将结构体转为NSValueNSValue *value = [NSValue valueWithPoint:p];
注意此时绝对不能这样写:
NSValue *value = @(p);这种写法只适用于NSNumber包装的类型。
如何将NSValue类型对象转为对应的结构体:
// 将value转为对应的结构体CGPoint p2 = [value pointValue];
8.NSDate类
NSDate是日期时间类,一个NSDate对象不仅包含了年月日信息,还有时间等信息,同时还有许多操作日期和时间的方法。
创建一个时间对象:当前时间
NSDate *date = [NSDate date]; // 默认依据当前时间打印时间:
NSLog(@"%@", date); // 2014-12-28 08:06:36 +0000创建一个时间对象:比date晚5秒钟
NSDate *date2 = [NSDate dateWithTimeInterval:5 sinceDate:date];
获取从1970年1月1日凌晨走过的秒数:
// 从1970开始走过的秒数NSTimeInterval seconds = [date2 timeIntervalSince1970];这里的NSTimeInterval实际是double类型:
typedef double NSTimeInterval;
获取date与当前时间的间隔:单位:妙
[date2 timeIntervalSinceNow];// Returns the interval between the receiver and the current date and time
日期格式化类的使用:
使用一:将date对象转为字符串:
void dateToString(){ NSDate *date = [NSDate date]; // 日期格式化类 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; // H(24小时制) h(12小时制) formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss"; NSString *strDate = [formatter stringFromDate:date]; NSLog(@"%@", strDate);}
使用二:将字符串转为日期:
void strToDate(){ NSString *time = @"2011/09/10 18:56"; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = @"yyyy/MM/dd HH:mm"; NSDate *date = [formatter dateFromString:time]; NSLog(@"%@", date);}
- ⑩--Foundation框架基础
- Foundation框架基础
- Foundation基础框架2
- cocoa foundation框架基础
- cocoa foundation框架基础
- Foundation框架基础 NSArray
- Foundation框架基础 NSString
- Foundation框架基础 NSSet
- iOS Foundation 基础框架
- Objective C Foundation基础框架
- cocoa foundation 框架基础实践
- Objective C Foundation基础框架
- 黑马程序员----foundation框架基础
- Foundation框架基础 NSDictionary-字典
- foundation框架基础 NSDate-日期
- Foundation框架基础 NSData-数据
- 黑马程序员--Foundation框架基础
- 黑马程序员-Foundation框架以及Foundation框架中的基础类
- 为每位消费者爱车担保200万美金保险,是任性,还是疯了?
- jquery取kindeditor插件的textarea的值
- 【Github教程】史上最全github使用方法:github入门到精通
- Sort Colors
- 【基础练习】【模拟】Uva489 - Hangman Judge题解
- ⑩--Foundation框架基础
- 20150117学习总结
- E - 1sting (递推+大数加法)
- 32位汇编语言学习笔记(45)--测试简单文件操作接口(完)
- Linux Barrier IO
- HDU1864 01背包
- 什么时候使用存储过程比较适合?
- leetcode-valid parenthesses
- jenkins持续构建