黑马程序员——零基础学习iOS开发——13 Foundation框架

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


Foundation框架是iOS以及Mac开发所需要的基础框架。

Foundation框架中包含了很多开发中常用的数据类型:结构体、枚举、类。

一、结构体

1.NSRange

从名字可以猜出是描述范围有关的,下面我们进入NSRange结构体的定义中去看一下它具体是什么。

我们可以通过下图所示的方法,进入NSRange在Foundation框架中的文件,看一下NSRange的庐山真面目~


黑马程序员——零基础学习iOS开发——13 Foundation框架_第1张图片


黑马程序员——零基础学习iOS开发——13 Foundation框架_第2张图片


1)NSRange原来就是由两个unsigned long类型组成的结构体:

2)NSRange的两个成员

NSRange有两个Unsigned long类型的成员:location、length

可以用来描述几个字母在字符串中所处的位置和长度。

也可以描述数组中几个数据所处的位置和范围。

// @"i love oc"  // 用NSRange描述字符串中love的范围

// 一般不用这种方法赋值
//NSRange r1 = {.location = 2, .length = 4};

// NSMaKeRange是系统自带的一个函数,一般用这种方法
NSRange r2 = NSMakeRange(2, 4);


3)用NSString的对象方法rangeOfString,查找某个字符串在str中的范围

    NSString *str = @"i love oc";
    
    // 用NSString的对象方法rangeOfString,查找“java”字符串在str中的范围
    // 如果找不到那个字符串,返回length=0,location=NSNotFound(枚举类型成员)==-1
    NSRange range = [str rangeOfString:@"java"];
    NSLog(@"loc = %ld, length=%ld", range.location, range.length);

2.NSPoint/CGPoint  

1)CGPoint用来表示UI元素在屏幕上的坐标位置

我们来看一下这个CGPoint又是个啥东东。这里我就不截图了,直接copy代码过来。

struct CGPoint {
   CGFloat x;
   CGFloat y;
};

typedef CGFLOAT_TYPE CGFloat;

# define CGFLOAT_TYPE double


typedef CGPoint NSPoint;

从上面4段代码我们可以看出,其实CGPoint就是两个double类型组成的结构体,而NSPoint和CGPoint是等价的。

开发中,我们一般用CGPoint,因为CGPoint是跨平台的。

2)可以给CGPoint/NSPoint赋值的两个函数

    CGPoint p1 = NSMakePoint(10, 10);
    NSPoint p2 = CGPointMake(20, 20);// 最常用



3.NSSize/CGSize 

1)CGSize用来表示UI元素的宽和高

是两个double类型组成的结构体。

struct CGSize {
  CGFloat width;
  CGFloat height;
};

2)CGSize类型变量的赋值

两个函数可以用来给CGSize类型变量赋值,NSMakeSize、CGSizeMake

    NSSize s1 = CGSizeMake(100, 50);
    NSSize s2 = NSMakeSize(100, 50);

4.NSRect/CGRect 

1)CGRect结构体嵌套了CGPoint和CGSize

struct CGRect {
   CGPoint origin;
   CGSize size;
};
typedef struct CGRect CGRect;

2)CGRect的3种赋值方式

    CGPoint p1 = NSMakePoint(10, 10);
    NSPoint p2 = CGPointMake(20, 20);// 最常用
    
    NSSize s1 = CGSizeMake(100, 50);
    NSSize s2 = NSMakeSize(100, 50);
    CGSize s3 = NSMakeSize(200, 60);
    
    // 第一种:CGrect r1 = CGRectMake(<#CGFloat x#>, <#CGFloat y#>, <#CGFloat width#>, <#CGFloat height#>)
    CGRect r1 = CGRectMake(0, 0, 100, 50);
    // 第二种:CGrect r2 = {CGPoint,CGSize}
    CGRect r2 = { {0, 3}, {100, 90}};
    // 第三种:CGrect r3 = {CGPoint,CGSize}
    CGRect r3 = {p1, s2};

3)Zero的使用

    // 表示原点
    // CGPointZero == CGPointMake(0, 0)
    
    // CGSizeZero == CGSizeMake(0, 0)
    
    // CGRectZero == CGRectMake(0, 0, 0, 0)
    
    // 使用CGPointZero等的前提是添加CoreGraphics框架
    CGRect r4 = {CGPointZero, CGSizeMake(100, 90)};

5.有关结构体的系统函数 

1)CGPointEqualToPoint(/Size/Rect)

1>用来比较两个点是否相同,返回值:BOOL类型,参数:两个CGPoint

2>既然Point可以比较,同样的,Size和Rect也有对应的这种函数

    // 比较两个点是否相同(x、y)
    BOOL b = CGPointEqualToPoint(CGPointMake(10, 10), CGPointMake(10, 10));
    
    // 比较两个Rect是否相同
    BOOL c = CGRectEqualToRect(CGRectMake(1, 1, 100, 50), CGRectMake(1, 1, 100, 50));
    
    // 比较两个Size是否相同
    BOOL d = CGSizeEqualToSize(CGSizeMake(10, 20), CGSizeMake(10, 20));

3>使用这个函数必须添加CoreGraphics框架

2)CGRectContainsPoint

1>用来判断一个点是否在一个Rect的范围内,返回值:BOOL类型,参数:一个CGRect、一个CGPoint

2>代码示例:

    // 判断点是否在一个范围内,Rect中 x的范围 50~150,y的范围40~90
    BOOL b2 = CGRectContainsPoint(CGRectMake(50, 40, 100, 50), CGPointMake(60, 45));
    
    NSLog(@"%d", b2);
3>使用这个函数必须添加 CoreGraphics框架

3)NSStringFromPoint(/Size/Rect)

用来将结构体Point、Size、Rect内容转为字符串,方便输出

    CGPoint p1 = NSMakePoint(10, 10);
    NSSize s1 = CGSizeMake(100, 50);
    CGRect r1 = CGRectMake(0, 0, 100, 50);
    
    // 用系统自带的3个函数,将3种结构体转为字符串
    NSString *str1 = NSStringFromPoint(p1);
    
    NSString *str2 = NSStringFromSize(s1);
    
    NSString *str3 = NSStringFromRect(r1);
    
    NSLog(@"%@", str1);
    NSLog(@"%@", str2);
    NSLog(@"%@", str3);

二、NSString和NSMutableString

1.NSString(不可变字符串)

字符串创建的几种方式:

    // 1.
    NSString *s1 = @"jack";
    // 2. 这个不常用,和第一种没区别
    NSString *s2 = [[NSString alloc] initWithString:@"jack"];
    // 3.
    NSString *s3 = [[NSString alloc] initWithFormat:@"age is %d", 10];
    // 4.
    // C字符串 转成 OC字符串
    NSString *s4 = [[NSString alloc] initWithUTF8String:"jack"];
    // OC字符串 转成 C字符串
    const char *cs = [s4 UTF8String];
    // 5.
    // NSUTF8StringEncoding 用到中文就可以用这种编码
    NSString *s5 = [[NSString alloc] initWithContentsOfFile:@"/Users/apple/Desktop/1.txt" encoding:NSUTF8StringEncoding error:nil];


2.URL(资源路径)

URL的书写格式

协议头://路径

协议头包括:http(网络资源)、ftp(FTP服务器资源)、file(本地文件)等

例如:http://weibo.com/a.png

    // NSURL *url = [[NSURL alloc] initWithString:@"file:///Users/apple/Desktop/1.txt"];
    NSURL *url = [NSURL fileURLWithPath:@"/Users/apple/Desktop/1.txt"];
    
    NSString *s6 = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"s6=\n%@", s6);


3.创建字符串的类方法

一般都会有一个与对象initWith方法配对的类方法。开发中,我们常用类方法,因为代码短,省时间。

     [NSURL URLWithString:<#(NSString *)#>];
     [NSString stringWithFormat:@""];
     [NSString stringWithContentsOfFile:<#(NSString *)#> encoding:<#(NSStringEncoding)#> error:<#(NSError *__autoreleasing *)#>];

4.字符串的导出

    // 将“Jack Jack”字符串写入my.txt文件中,如果没有my.txt文件,则自动创建
    // atomically属性:如果字符串写入失败,是否删除新建的文件
    [@"Jack\nJack" writeToFile:@"/Users/apple/Desktop/my.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
    
    // 将字符串str写入到URL路径资源中
    NSString *str = @"4234234";
    NSURL *url = [NSURL fileURLWithPath:@"/Users/apple/Desktop/my2.txt"];
    [str writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];

5.字符串的导入

/*
     字符串的导入
     */
    // 将本地文件1.txt的全部内容导入str9这个字符串
    NSString *str9 = [NSString stringWithContentsOfFile:@"/Users/apple/Desktop/1.txt" encoding:NSUTF8StringEncoding error:nil];
    // 将http://www.baidu.com页面的内容全部导入str10这个字符串
    NSString *str10 = [NSString stringWithContentsOfURL:@"http://www.baidu.com" encoding:NSUTF8StringEncoding error:nil];

6.NSMutableString(可变字符串)

1)可变字符串的拼接:

这里用到了字符串对象方法 appendString:

NSMutableString *s1 = [NSMutableString stringWithFormat:@"my age is 10"];
    // 拼接内容到s1的后面
    [s1 appendString:@" 11 12"];
输出s1的结果是:my age is 10 11 12

2)不可变字符串拼接后新建字符串

    // s2 是不可变字符串
    NSString *s2 = [NSString stringWithFormat:@"age is 10"];
    // s2内容拼接 11 12后,保存至新建的s3中,因为s2是不可变字符串
    NSString *s3 = [s2 stringByAppendingString:@" 11 12"];


3)删除字符串中的某个字符串

    NSMutableString *s1 = [NSMutableString stringWithFormat:@"my age is 10"];
  
    // 获取is在s1中的范围
    NSRange range = [s1 rangeOfString:@"is"];
    // 删除 s1字符串中的 range范围内的 字符串
    [s1 deleteCharactersInRange:range];
    
    // 一般不用下面这种方法,如果s1的长度变了,又要重新输出Range中的数字
    //[s1 deleteCharactersInRange:NSMakeRange(8, 2)];

三、集合类 NSArray和NSMutableArray(OC数组)

1.可变数组、不可变数组

NSArray:不可变数组

NSMutableArray:可变数组

NSMutableArray是NSArray的子类

2.OC数组与C语言数组的区别

C语言数组:只能存放单一类型数据

     int a = 5; 
     int ages[10] = {1, 90, 89, 17};

     Person *p = [[Person alloc] init];
     Person *persons[5] = {p, [[Person alloc] init]};

OC数组:可以存放各种OC对象  

* OC数组不能存放nil值,nil代表OC数组的结束。

* OC数组只能存放OC对象、不能存放非OC对象类型,比如intstructenum 

    // 不可变数组创建好以后就不能改变,下面这个array永远是空数组
    // NSArray *array = [NSArray array];

3.NSArray的基本使用

    /*
     1.NSArray的创建
     */
    NSArray *array2 = [NSArray arrayWithObject:@"jack"];
    
    // nil是数组元素结束的标记
    NSArray *array3 = [NSArray arrayWithObjects:@"jack", @"rose", nil];
    // [array2 count];
    
    //NSArray *array4 = [NSArray arrayWithObjects:@"jack", @"rose", @"4324324", nil];
    
    // 快速创建一个NSArray对象
    NSArray *array4 = @[@"jack", @"rose", @"4324324"];
    
    
    /*
     2.NSArray的元素个数
     */
    NSLog(@"%ld", array3.count);
    
    
    /*
     3.NSArray中元素的访问
     */
    NSLog(@"%@", [array3 objectAtIndex:1]);
    
    // array3[1];这中模仿C语言的写法是编译器特性
    NSLog(@"%@", array3[1]);

4.OC数组的遍历

    // 遍历OC数组的3种方法
    
    Person *p = [[Person alloc] init];
    
    NSArray *array = @[p, @"rose", @"jack"];
    
     // 第一种
        for (int i = 0; i


5.可变数组

1)可变数组的基本使用:

    NSMutableArray *array = [NSMutableArray arrayWithObjects:@"rose", @"jim", nil];
    
    // 添加元素
    [array addObject:[[Person alloc] init]];
    
    [array addObject:@"jack"];
    
    // 删除元素
    //[array removeAllObjects];
    // 删除指定的对象
    // [array removeObject:@"jack"];
    [array removeObjectAtIndex:0];
    
    // 错误写法
    // [array addObject:nil];
    
    
    NSLog(@"%@", array);
    
    NSLog(@"%ld", array.count);

2)@[] 只能用来创建不可变数组NSArray,因为@[]的返回值是NSArray类型。

四、集合类 NSSet和NSMutableSet (无序数组)

1.NSSet 无序不可变数组

    // 创建了一个空无序数组,这个数组永远是空的,因为是不可变数组
    NSSet *s = [NSSet set];
    
    // 创建了一个不可变无序数组
    NSSet *s2 = [NSSet setWithObjects:@"jack",@"rose", @"jack2",@"jack3",nil];
    
    // 从无序数组s2中随机拿出一个元素
    NSString *str =  [s2 anyObject];
    
    NSLog(@"%@", str);
    // 输出数组长度
    NSLog(@"%ld", s2.count);

2.NSSetNSArray的对比

 1>共同点

 * 都是集合,都能存放多个OC对象

 * 只能存放OC对象,不能存放非OC对象类型(基本数据类型:intcharfloat等,结构体,枚举)

 * 本身都不可变,都有一个可变的子类

 

 2>不同点

 * NSArray有顺序,NSSet没有顺序


3.NSMutableSet 无序可变数组

    // 创建一个空的无序可变数组
    NSMutableSet *s1 = [NSMutableSet set];
    
    // 添加元素1
    [s1 addObject:@"hack"];
    
    NSArray *a = [NSArray arrayWithObjects:@"kevin", @"miky",@"james", nil];
    // 添加元素2  把数组a中的元素添加到无序数组s1中
    [s1 addObjectsFromArray:a];
    
    // 删除元素
    [s1 removeObject:@"hack"];

五、集合类  NSDictionary和NSMutableDictionary (字典)

     字典:一个key(键)对应一个value(值),里面存储的东西都是键值对。 

     key(id类型) ----> value(id类型)

     一般用法:索引 ---->文字内容


    字典不允许有相同的key,但允许有相同的valueObject

   字典是无序的


1.不可变字典 NSDictionary

    // 创建一个不可变字典,它永远只有这一对键值
    NSDictionary *dict1 = [NSDictionary dictionaryWithObject:@"jack" forKey:@"name"];
    
    
    NSArray *keys = @[@"name", @"address"];
    NSArray *objects = @[@"jack", @"北京"];
    // 将有序数组 keys、objects中的元素传入字典,作为字典的keys和objects
    NSDictionary *dict2 = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
    
    
    // 创建一个拥有多对键值的不可变字典
     NSDictionary *dict3 = [NSDictionary dictionaryWithObjectsAndKeys:
     @"jack", @"name",
     @"北京", @"address",
     @"32423434", @"qq", nil];
    
    // Xcode的编译器特性,简化了创建多对键值字典的代码
    // 冒号左边写key,右边写value,每对键值用逗号隔开
    NSDictionary *dict4 = @{@"name" : @"jack", @"address" : @"北京"};
    
    // 取出字典dict4中key name所对应的值
    id obj1 = [dict4 objectForKey:@"name"];
    // Xcode编译器特性,简化了从字典中取值的代码
    id obj2 = dict4[@"name"];
    
    NSLog(@"%@", obj2);
    
    // 返回的是键值对的个数
    NSLog(@"%ld", dict4.count);

2.可变字典 NSMutableDictionary

// 创建可变字典
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    
    // 添加键值对
    [dict setObject:@"jack" forKey:@"name"];
    // 如果给一个key多次添加值,最后添加的值会覆盖之前的值
    // 这一行过后,rose覆盖了原来的jack
    [dict setObject:@"rose" forKey:@"name"];
    
    [dict setObject:@"北京" forKey:@"address"];
    
    [dict setObject:@"1223242" forKey:@"qq"];
    
    // 移除键值对
    [dict removeObjectForKey:@"qq"];
    
    // 取出name对应的值
    NSString *str = dict[@"name"];
    
    NSLog(@"%@", str);
    // 输出字典
    NSLog(@"%@", dict);

可变字典使用注意:

    // 这样做是不合理的,@{@"key":"value"}返回的是NSDictionary类型对象(是不可变的),不能赋值给一个可变字典
    NSMutableDictionary *dict = @{@"name" : @"jack"};
    // 这一句会报错,dict实际是不可变字典类型,不可变字典没有set开头的方法
    [dict setObject:@"rose" forKey:@"name"];

3.字典的遍历

    // 字典不允许有相同的key,但允许有相同的value(Object)
    // 字典的无序的
    NSDictionary *dict = @{
    @"address" : @"北京",
    @"name" : @"jack",
    @"name2" : @"jack",
    @"name3" : @"jack",
    @"qq" : @"7657567765"};

    // 用Block方法遍历字典
    [dict enumerateKeysAndObjectsUsingBlock:
     ^(id key, id obj, BOOL *stop) {
         NSLog(@"%@ - %@", key, obj);
         
         // *stop = YES; // 用来停止遍历
     }];
    
    // 用for循环遍历字典
    // 一般不用这个方法,用上面的Block更方便
    // 1.allkeys方法取出字典所有的key
    // 2.for循环每次取出一个key对应的值
        NSArray *keys = [dict allKeys];
    
        for (int i = 0; i


六、集合类总结

 集合

 1.NSArray\NSMutableArray

 *有序

 *快速创建(不可变):@[obj1, obj2, obj3]

 *快速访问元素:数组名[i]

 2.NSSet\NSMutableSet

 *无序 

 3.NSDictionary\NSMutableDictionary

 *无序

 *快速创建(不可变):@{key1 : value1,  key2 : value2}

 *快速访问元素:字典名[key]

4.几种可读性较差的写法(需要能看懂)

    // 一个通讯录中,包含4个人
    // 一个数组,存了4个字典对象
    NSArray *persons = @[
    // books这个key对应的value是一个数组
    @{@"name" : @"jack", @"qq" : @"432423423", @"books": @[@"5分钟突破iOS编程", @"5分钟突破android编程"]},
    @{@"name" : @"rose", @"qq" : @"767567"},
    @{@"name" : @"jim", @"qq" : @"423423"},
    @{@"name" : @"jake", @"qq" : @"123123213"}
    ];
    
    // 先取出persons数组[1]位置对应的字典
    // 再取出字典中qq这个key对应的数据
    NSLog(@"%@", persons[1][@"qq"]);
    
    // 先取出persons数组[0]位置对应的字典
    // 再取出字典中books这个key对应的数组
    // 再取出数组中[1]位置存的书名
    NSString *bookName = persons[0][@"books"][1];
    NSLog(@"%@", bookName);
    
    // 先取出persons数组[0]位置的字典
    // 再取出字典中中books这个key所对应的数组
    NSArray *array = persons[0][@"books"];
    NSLog(@"%@", array);


七、NSValue/NSNumber

1.简介

在OC数组和字典中,只能存放OC对象。如果我们想传一个基本数据类型到数组中,比如int类型,只能将int包装成字符串对象:@“20”。

OC中提供这两个类NSValue、NSNumber,可以将任何基本数据类型转成NSValue或NSNumber类型的对象。

* NSNumber是NSValue的子类

* NSValue可以包装任何基本数据

* NSNumber只能包装数字(int、double、floa、BOOL、enum)

2.NSNumber的基本使用

1)基本用法

    // int数据 ---> NSNumber对象

    // 将基本数据类型int包装成NSNumber类型的OC对象
    NSNumber *num = [NSNumber numberWithInt:10];
    
    NSDictionary *dict =  @{
    @"name" : @"jack",
    // 将包装好的NSNumber对象num传入字典
    @"age" : num
    };
    
    NSNumber *num2 = dict[@"age"];
    
    // NSNuber对象 ---> int数据
    
    // 将Number类型对象 转成int类型数据
    int a = [num2 intValue];
    
    NSLog(@"%d" , a);


其他基本数据类型的方法名我们很容易猜到,比如double类型:

NSNumber *n = [NSNumber numberWithDouble:10.5];
    
    int d = [n doubleValue];
在平时使用中,可以多尝试一下其他方法,这里就不一一列举了。

2)编译器特性


// @20:将20包装成一个NSNumber对像
    NSArray *array = @[
    
    @{@"name" : @"jack", @"age" : @20},
    
    @{@"name" : @"rose", @"age" : @25},
    
    @{@"name" : @"jim", @"age" : @27}
    ];
    
    
    // 将各种基本数据类型包装成NSNumber对象
    @10.5;
    @YES;
    @'A'; // NSNumber对象

    
    // 将age变量包装成NSNumber对象
    int age = 100;
    @(age); // 包装变量时,变量要用小括号包住
    //[NSNumber numberWithInt:age];

3.NSValue的基本使用

NSValue一般用于包装结构体:CGPoint、CGSize、CGRect

    // 结构体 ---> Value类型的OC对象
    
    // 这是一个结构体
    CGPoint p = CGPointMake(10, 10);
    // 将结构体转为Value对象
    NSValue *value = [NSValue valueWithPoint:p];
    // 将value对象存入OC数组
    NSArray *array = @[value];
    
    
    // value类型对象 ---> 结构体
    
    // 将value转成CGPoint类型结构体
    CGPoint p1 = [value pointValue];
同样的,也有对应的用于CGSize和CGRect的方法,这里就不举例了。


八、NSDate 时间

1.基本使用

    // 创建一个时间对象,默认的时间是执行这段代码的时间
    NSDate *date = [NSDate date];
    // 打印出的时候是0时区的时间(北京是东8区)
    NSLog(@"%@", date);
    
    // 创建一个date2 ,比date的时间晚5秒
    NSDate *date2 = [NSDate dateWithTimeInterval:5 sinceDate:date];
    
    // TimeInterval实际就是double类型
    
    // 从1970开始走过的秒数
    NSTimeInterval seconds = [date2 timeIntervalSince1970];
    
    // 从date2到执行这段代码时,走过的秒数
    [date2 timeIntervalSinceNow];


2.时间格式化

当我们想把NSDate对象中的时间输出到手机屏幕上时,我们就需要将NSDate对象转成字符串。

但如何告诉程序我们想要用什么格式输出呢?2015\04\07 还是 2015-04-07 11:10:36? 用24时制还是12时制?

这就用到了时间格式类:NSDateFormatter


1)将NSDate对象转成字符串

    // NSDate对象 ---> 字符串
    
    // 创建时间对象date
    NSDate *date = [NSDate date];
    
    // 日期格式化类
    // 创建了一个日期格式化类的对象
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    
    // 设置日期格式化对象的dateFormat属性(日期格式属性)
    // y 年  M 月  d 日
    // m 分 s 秒  H (24)时  h(12)时
    formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    
    // 用对象方法,将date对象转成字符串
    NSString *str = [formatter stringFromDate:date];
    
    NSLog(@"%@", str);

2)将字符串转成NSDate对象

    // 字符串 ---> NSDate对象
    
    // 1.取得一个字符串
    NSString *time = @"2011/09/10 18:56";
    // 2.设置时间显示格式
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"yyyy/MM/dd HH:mm";
    // 3.根据格式将字符串转成时间
    NSDate *date = [formatter dateFromString:time];
    NSLog(@"%@", date);


小结

1.结构体一般用CG前缀而不用NS,CG是跨平台的。

2.调用CG开头的函数需要添加CoreGraphics框架
3.NSMutable开头的类都是可变的,都是不带Mutable的类的子类

4.基本数据类型与OC对象的转换:NSValue/NSNumber

5.默认显示时间是0时区的时间,北京是东8区。时间格式化:NSDateFormatter


To be continue……


你可能感兴趣的:(iOS开发0基础自学)