美文网首页
iOS 相关集合函数的使用

iOS 相关集合函数的使用

作者: _凉风_ | 来源:发表于2016-06-23 17:05 被阅读347次

    一、结构体

    1. NSRange 范围

    • 定义
    typedef struct _NSRange{ 
        NSUInteger location;// NSUInteger结构体是 unsign long int 类型
        NSUInteger length;
    } NSRange;
    
    • 创造结构体
    NSRange r1 = {2, 4}; // 方法1:不常用
    NSRange r2 = {.location = 2, .length = 4}; // 方法2:不常用
    NSRange r3 = NSMakeRange(2, 4); // 方法3:Foundation框架自带函数
    
    • NSString 中的 rangeOfString(查找字符串) 方法
      作用:查找字符串在本字符串中的范围,返回 NSRange 结构体
      注意:如果 查找字符串未找到,返回的 NSRange 结构体 length = 0, location = NSNotFound 「NSNotFound 为枚举类型 为常量整数 -1」

    2. NSPoint UI元素的位置

    • 定义
    typedef struct CGPoint{ 
        // CGFloat结构体 是double类型
        CGFloat x; // 在UI界面中 x 向右递增
        CGFloat y; // 在UI界面中 y 向下递增
    } CGPoint;
    typedef CGPoint NSPoint; // 开发用 CGPoint,因为它跨平台
    
    • 创造结构体
    CGPoint p1 = NSMakePoint(2, 4); // 方法1:Foundation框架自带函数
    NSPoint p2 = CGPointMake(2, 4); // 方法2:开发中常用,CGPoint 和 NSPoint等价
    
    • CGPointZero「常量」等价于 CGPointMake(0, 0);
    • <code>bool CGPointEqualToPoint(CGPoint , CGPoint)</code> 比较两个点位置是否相同

    3. NSSize UI元素的尺寸

    • 定义
    typedef struct CGSize{ 
        CGFloat width;// CGFloat结构体 是double类型
        CGFloat height;
    } CGSize;
    typedef CGSize NSSize; // 开发用 CGSize,因为它跨平台
    
    • 创造结构体
    CGSize s1 = NSMakeSize(2, 4); // 方法1:Foundation框架自带函数
    NSSize s2 = CGSizeMake(2, 4); // 方法2:开发中常用,CGSize 和 NSSize等价
    
    • CGSizeZero「常量」等价于 CGSizeMake(0, 0);
    • <code>bool CGSizeEqualToSize(CGSize , CGSize)</code> 比较

    4. NSRect 矩形UI元素的 左上角的位置 和 尺寸

    • 定义
    typedef struct CGRect{ 
        CGPoint origin;
        CGSize size;
    } CGRect;
    
    • 创造结构体
    CGRect rect = { CGPointMake(2, 4), NSMakeSize(2, 4) };
    
    • CGRectZero「常量」等价于 CGRectMake(0, 0, 0, 0);

    • <code>bool CGRectEqualToRect(CGRect , CGRect)</code> 比较「Foundation框架」

    • <code>bool CGRectCotainsPoint(CGRect, CGPoint)</code>判断 点是否在矩形范围内「CoreGraphics框架」

    • <code>bool CGRectCotainsRect(CGRect, CGRect)</code>判断 矩形是否在矩形范围内「CoreGraphics框架」

    • 将结构体 转成字符串

    NSString *str = NSStringFromCGRect(CGRect rect);
    NSLog("%@", str);
    

    打印效果:
    <code>{ {0, 0}, {0, 0} }</code>

    二、类

    1. NSString「不可变字符串」

    • 字符串的创建方式
    NSString *s1 = @"方法  1";
    NSString *s2 = [[NSString alloc] initWithString:@"方法 2"];
    NSString *s3 = [[NSString alloc] initWithFormat:@"方法 %d", 3];
    NSString *s4 = [[NSString alloc] initWithUTF8String:"方法 4:C字符串 转 OC字符串"];
    const char *s = [s4 UTF8String]; // OC字符串 转 C字符串
    // 一般都有一个类方法和对象方法配对,方法名为 类名With...
    NSString *s5 = [NSString stringWithFormat:@"方法 5"];
    
    NSString *s6=[NSString stringWithContentsOfFile:@"/绝对路径 方法 6" encoding:NSUTF8StringEncoding error:nil];
    
    • 读取文件
    // 方法 1:从本地读取
    NSString *s1=[[NSString alloc] initWithContentsOfFile:@"/绝对路径" encoding:NSUTF8StringEncoding error:nil];
    // 方法 2:从 URL 读取
    // URL 格式:协议头://路径「[file://](http://file//) 本地,[ftp://](http://ftp//) , [http://](http:/) 」
    NSURL *url = [[NSString alloc] initWithString:@"[file://](http://file//)/绝对路径"]; // 前面"//"是URL格式,后面"/"代表根路径
    NSURL *url1 = [NSURL fileURLWithPath:@"/绝对路径"]; // 已经调用的 file方法,无序传入URL的协议头来声明文件类型
    NSString *s2 = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    
    • 写入文件「字符串导出」
    // atomically: YES 只有写入完成后才创建文件
    // atomically: NO 只要写入就创建文件,不管其是否完整,都创建文件
    [@"写入内容对象" writeToFile:@"/路径、创建写入文件名称" atomically:YES encoding:NSUTF8StringEncoding error:nil];
    
    NSURL *url = [[NSString alloc] initWithString:@"[file://](http://file//)/绝对路径"];
    [@"写入内容对象" writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];
    
    • NSMutableString「继承自NSString,可变字符串」
    // 添加到原来字符串后面,返回添加后的新对象「原来字符串不变」
    NSString *s = [NSString stringWithFormat:@"可变字符串"];
    NSString *s0 = [s appendString:@"添加的字符串"];
    
    // 添加到原来字符串后面「原来字符串变」
    NSMutableString *s1 = [NSMutableString stringWithFormat:@"可变字符串"];
    [s1 appendString:@"添加的字符串"];
    
    // 删除字符串的一些字符
    NSRange range = [s1 rangeOfString:@"加"];
    [s1 deleteCharacterInRange: range];
    
    • 字符串比较
    NSString *s1 = @"abd";
    NSString *s2 = @"abc";
    
    // 比较「内容」是否相同
    BOOL result = [s1 isEqualToString: s2];
    // 比较「地址」是否相同
    result = (s1 == s2);
    
    // 比较「大小」是否相同
    // 返回值:
    //    NSOrderedAscending     前 < 后
    //    NSOrderedSame            相同
    //    NSOrderedDescending    前 > 后
    result = [s1 compare: s2];
    // 比较「大小」是否相同,忽略大小写
    result = [s1 caseInsensitiveCompare: s2];
    
    • 字符串搜索
    NSString *s = @"[http://www.baidu.com";](http://www.baidu.com";)
    // 判断以什么开头
    BOOL result = [s hasPrefix: @"[http://](http://"];)"];
    
    // 判断以什么结尾
    BOOL result = [s hasSuffix: @".com"]; 
    
    // 判断是否包涵给定的字符串
    //     若包涵,返回给定字符串的 1.起始位置 2.该字符串的长度
    NSRange rr = [s rangeOfString: @"bai"]; // 默认:从前往后查找
    NSRange rr = [s rangeOfString: @"bai" options:NSBackWardsSearch];
    
    • 字符串截取
    NSString *s = @"<head>要截取的字符串</head>";
    NSRange range = {6, 7}; // 设置获取字符串范围
    NSString *get = [s substringWithRange: range];
    
    // 从 什么地方 开始截取,一直截取到 最后
    get = [s subStringFromIndex: 6];
    // 从 开头 开始截取,一直截取到 哪个位置
    get = [s subStringToIndex: 7];
    
    • 字符串替换
    NSString *s = @"ni hao hehe";
    // stringByReplacingOccurrencesOfString: 被替换的字符串
    // withStirng: 用什么替换
    NSString *newStr = [s stringByReplacingOccurrencesOfString: @"hehe" withString: @"haha"];
    
    // 首末位 去除
    NSCharacterSet *set = [NSCharacterSet whitespaceCharacterSet];
    newStr = [s stringByTrimmingCharactersInSet: Set]; // 将首末位 去除set对象类型的字符串
    
    • 字符串路径相关方法
    NSString *str = @"/h/a/c.c";
    // 1.判断是否是绝对路径「判断字符串是否以'/'开头」
    BOOL *op = [s isAbsolutePath];
    
    // 2.获取文件路径中的最后一个目录「删除最后一个'/'以及其后面的内容」
    NSString *newStr2 = [str lastPathComponent];
    
    // 3.删除文件路径的最后一个目录「获取最后一个'/'的内容」
    NSString *newStr3 = [str stringByDeletingLastPathComponent];
    
    // 4.给文件添加一个目录「返回 字符串末尾 + / + 指定内容,若给定内容含有 / 则不会重复添加,若给定内容有重复的 / 则只保留一个」
    NSString *newStr4 = [str stringByAppendingPathComponent:@"添加的文件名"];
    
    // 5.获取路径中文件的扩展名「从字符串末尾开始 截取第一个 . 后面的内容」
    NSString *newStr5 = [str pathExternsion];
    
    // 6.删除路径中文件的扩展名「从字符串末尾开始 删除第一个 . 后面的内容」
    NSString *newStr6 = [str stringByDeletingPathExternsion];
    
    // 7.给文件路径添加一个扩展名
    NSString *newStr7 = [str stringByAppendingPathExternsion: @"mm"];
    

    2. NSArray「集合类」

    • 存储对象 有序
    • 是 OC数组,只能存放OC对象「对象类型不必一致」
    • 数组里可以装入 字典类
    • 不能存放 nil 值、非OC对象类型「比如:int、struct、enum等」
    • NSArray:不可变有序数组
    // NSArray 对象创建
    NSArray *array0 = [NSArray arrayWithObject:@"创建含有一个对象的字符串数组"];
    NSArray *array1 = @["对象1", @"对象2"]; // 编译器会把本句转换为以下一句「编译器特性」,只返回不可变数组 NSArray
    NSArray *array2 = [NSArray arrayWithObjects:@"对象1", @"对象2", nil]; // nil是元素结束的标记,必不可少
    
    // NSArray 元素个数
    NSLog(@"%ld", array2.count); // 打印array2的数组元素个数,这里 = 2
    
    // NSArray 元素访问
    array2[0]; // 编译器自动转为 以下这句
    [array2 objectAtIndex:0];
    
    // NSArray 快速遍历 1
    //  id obj代表数组中的每一个元素
    for(id obj in array2){ 
        NSUInteger i = [array2 indexOfObject: obj]; // 找出obj元素在数组中的位置
        NSLog(@"%ld - %@", i, obj);
    }
    
    // NSArray 快速遍历 2
    //  每遍历一个元素就会调用 block,并把 当前元素和索引位置 传给block
    //  每次遍历会检测 *stop的值,若为 YES可提前跳出循环
    [arrary2 enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
    
        NSLog(@"%ld - %@", idx, obj);
        if(idx==1) *stop = YES;
    }];
    
    • NSMutableArray:可变有序数组「继承自 NSArray」
    // 数组创建
    NSMutableArray *array = [NSMutableArray array];
    
    // 元素添加
    [array addObject:@"可添加任何对象,但不能添加 基本数据类型"];
    
    // 删除元素
    [array removeAllObjects]; // 删除所有元素
    [array removeObject:@"删除指定对象"];
    [array removeObjectAtIndex:0]; // 删除下标为0的元素,后面元素自动往前移动
    

    3. NSSet「集合类」

    • 存储对象 无序
    • 不能存放 nil 值、非OC对象类型「比如:int、struct、enum等」
    • NSSet: 不可变无序数组
    // 无序数组创建
    NSSet *set0 = [NSSet setWithObject:@"创建含有一个对象的字符串数组"];
    NSSet *set1 = @["对象1", @"对象2"]; // 编译器会把本句转换为以下一句「编译器特性」
    NSSet *set2 = [NSSet setWithObjects:@"对象1", @"对象2", nil]; // nil是元素结束的标记,必不可少
    // 随机返回一个对象
    NSString *str = [set0 anyObject];
    // 删除对象
    [set0 removeAllObjects]; // 删除所有元素
    [set0 removeObject:@"删除指定对象"]; 
    
    • NSMutableSet: 可变无序数组「继承自 NSSet」

    4. NSDictionary「集合类」

    • 不可变、无序集合类
    • 集合类型不必一致
    • 存储 键值对:key —> value「key值唯一,value值不唯一」
    • 如果给出的键 无对应的值,则返回 nil「空」
    // 根据键值,创建单元素字典集合对象
    NSDictionary *dict = [NSDictionary dictionaryWithObject:@"value" forKey:@"keyName"];
    // 创建多元素集合对象 1
    NSArray *keys = @[@"keyName",@"address"];
    NSArray *objects = @[@"nameValue",@"addressValue"];
    
    NSDictionary *dict = [NSDictionary dictionaryWithObjects:objects forKey:keys];
    // 创建多元素集合对象 2
    NSDictionary *dict1 = @{@"key1":@"value1", @"key2":@"value2"}; //「编译器特性」只有不可变字典类才会用此方法,自动生成以下代码
    NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:@"value1",@"key1", @"value2",@"key2", nil];
    
    // 根据键,获取值
    id objValue1 = dict[@"keyName"]; //「编译器特性」自动生成以下代码
    id objValue1 = [dict objectForKey:@"keyName"];
    
    // 获取 键值对的 对数
    NSLog(@"%ld", dict1.count); // 这里 打印的值是 2
    
    • NSMutableDictionary「可变集合类,继承自NSDictionary」
    // 创建 空 可变集合类
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    // 添加键值对
    [dict setObject:"value1" forKey:@"keyName1"];
    
    [dict setObject:"value2" forKey:@"keyName1"]; // 当再次给key赋值时,旧值会被新值覆盖
    
    // 移除键值对
    [dict removeObjectForKey:@"keyName1"];
    
    // 打印字典类
    NSLog(@"%@", dict);
    // 打印效果
    NSDictionary{
        keyName1 = value2;
        keyName2 = value2;
    }
    
    // 字典遍历 1
    NSArray *keys = [dict allKeys]; // 取出字典类所有的 key值作为一个有序的数组
    for(int i=0; i<dict.count; i++){
        NSArray *key = keys[i];
        NSArray *obj = dict[key];
        NSLog(@"%@ = %@", key, obj);
    }
    // 字典遍历 2
    [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){
        NSLog(@"%@ = %@", key, obj); // *stop = YES; 时提前停止
    }];
    
    // 数组类嵌套字典类
    NSArray *persons = @[
        @{@"key1":@"value1", @"key2":@"value2"}, //字典类 0
        @{@"key3":@"value3", @"key4":@"value4"}  //字典类 1
    ];
    NSLog(@"%@", persons[0]); // 输出 字典类 0
    NSLog(@"%@", persons[0][@"key1"]); // 输出 value1
    

    5. 基本数据类型 转换为 OC类

    • 将 基本数据类型 转换为 NSNumber对象「in、char、float、double、short、long、long long」
    NSNumber *n = @10; //「编译器特性」自动生成以下代码
    NSNumber *n = [NSNumber numberWithInt:10]; // 此外还有:@YES、@'A'、@5.21
    
    // 将 变量 包装成 NSNumber对象
    int age = 20;
    NSNumber *n1 = @(age); //「编译器特性」自动生成以下代码
    NSNumber *n1 = [NSNumber numberWithInt:age]; 
    
    // C语言字符串转换为 OC字符串
    char *c = "init_a_C_string";
    NSString *oc = @(c);
    
    • 将 NSNumber对象 转换为 基本数据类型
      <code>int i = [n intValue];</code>
    • NSNumber因为继承了 NSValue 所以能包装基本数据类型为对象
      NSValue 可以将 结构体 转换 为对象
    CGPoint *p = CGPointMake(10, 10);
    NSValue *v = [NSValue valueWithPoint: p]; // 将结构体 包装成 NSValue对象
    NSArray *a = @[v]; // 将包装后的对象放入数组集合中使用
    

    6. NSDate

    // 创建时间对象
    NSDate *date  = [NSDate date];
    // 打印时间「打印的为0时区的时间,不是本时区的时间」
    NSLog(@"%@", date);
    
    • NSDateFormatter 日期格式化类
    // 日期 -> 字符串
    NSDate *date = [NSDate date];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    // y=年、M=月、d=日、m=分、s=秒、H=时「24小时制」、h=时「12小时制」
    formatter.datFormat = @"yyyy-MM-dd HH:mm:ss";  // 设定日期格式
    NSString *str = [formatter stringFromDate: date]; // 将 日期 转为 字符串
    
    // 字符串 -> 日期
    NSString *time = @"2016-02-13 23:49";
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    
    formatter.datFormat = @"yyyy-MM-dd HH:mm";  // 设定日期格式
    NSDate *date = [formatter dateFromString: time]; // 将 字符串 转为 日期
    

    7. NSCalendar

    NSDate *now = [NSDate date];
    // 创建日历对象「非单例对象」
    NSCanlendar *calendar1 = [NSCanlendar currentCanlendar];
    // 利用日历类,从当前 Date对象中 单独获取 年月日时分秒
    // components:获取多个枚举类型参数
    NSCanlendatUnit type = NSCanlendatUnitYear | NSCanlendatUnitMonth; // 通过 | 链接多个枚举值
    NSDateComponents *cmps = [calendar1 components:type fromDate now];
    NSLog(@"Year = %ld", cmps.year);
    
    // 比较两个时间的差值
    // 设置过去的时间
    NSString *ss =@"2016-2-17 4:27:26 +0000";
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormatter = @"yyyy-MM-dd hh:mm:ss Z";
    NSDate *date = [formatter dateFromString: ss];
    NSDateComponents *cmp1 = [calendar components:type fromDate:date toDate:now options:0];
    

    8. 集合对象的内存管理

    • 若将对象添加到数组中,则数组会对对象进行 一次 retain
    • 数组对象释放,会给数组所有对象发送一条 release 消息
    • 数组移除对象,会给移除的对象发送一条 release 消息

    9. copy

    定义:利用一个源 文件/对象,产生一个副本 文件/对象
    特点:修改副本对象不会引起原对象的改变
    方法:

    • copy:创建不可变副本(NSString、NSArray、NSDictionary)
      不会生成新对象,copy的对象是原来的那一个对象「浅拷贝:指针拷贝」
      因为都不可变,所以为了优化内存,不会生成新对象
      使用copy功能的前提:遵守NSCopying协议,实现 copyWithZone:方法
    • MAC平台下,不可变副本使用copy方法,不会 对原来对象进行 一次retain
    • IOS平台下,不可变副本使用copy方法, 对原来对象进行 一次retain
    // s 为 不可变字符串
    NSString *s = @"Hello";
    NSString *s1 = [s copy]; //不会产生新对象「都是不可变,不用另外开辟空间复制,浅复制」
    NSLog(@"s的地址:%p s1的地址:%p", s, s1);
    
    • mutableCopy:创建可变副本(NSMutableString、NSMutableArray、NSMutableDictionary)
      使用 mutableCopy 功能前提:遵守NSMutableCopying协议,实现 mutableCopyWithZone: 方法
      会生成新对象,mutableCopy 的对象是一个新对象「深拷贝:内容拷贝」
    • 由于生成新对象,在任何平台下都 不会 对原来对象进行 一次 retain
      只会对新对象进行 一次 retain
    NSMutableString *s2 = @"Hey";
    NSMutableString *s3 = [s2 copy]; // 不会产生新对象「浅复制」
    NSMutableString *s4 = [s2 mutableCopy]; // 会产生新对象「深复制」
    NSLog(@"s2的地址:%p s3的地址:%p s4的地址:%p",s2, s3, s4);
    
    • copy block 之后引发循环引用
      如果对象中 block 又用到了对象本身,那么为了避免内存泄露,应该将对象修饰为 __block
    typedef myBlock 
    @interface Person:Object
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, copy) 
    @end
    int main(){
        __block Person *p = [[Person alloc] init]; // [p retainCount] == 1
        p.name = @"原来对象";
        p.pBlock = ^(){
            NSLog(@"name = %@", p.name); // [p retainCount] == 2
        }
        p.pBlock;
        [p release]; // [p retainCount] == 1
        return 0;
    }
    

    自定义类实现 copy 操作

    • 遵守 NSCopying 协议
    • 实现 copyWithZone:该方法返回对象的副本
      创建一个新对象,并设置该对象数据与现有对象一致,返回该对象
    • zone:表示 分配对象需要的内存空间,避免出现堆内存碎片而使用「古老的技术,系统指定,几乎可以忽略」
    // Student 父类
    @implememt Person
    - (id) copyWithZone:(NSZone *)zone{
        // 1.创建一个新对象
        Person *p = [[[self class] allocWithZone:zone] init];
        // 2. 设置当前对象值为新的对象
        p.age =_age;
        p.name = _name;
        // 3. 返回新对象
        return p;
    }
    @end
    
    // Person 子类
    @implememt Student
    // 想要子类copy保留子类的属性,必须重写copyWithZone:方法
    - (id) copyWithZone:(NSZone *)zone{
        // 1. 使用父类函数,创建副本,设置值
       id obj = [super copyWithZone: zone];
        // 2. 设置子类特有的值
       [obj setHeight:_height];
        // 3. 返回新对象
        return p;
    }
    @end
    

    相关文章

      网友评论

          本文标题:iOS 相关集合函数的使用

          本文链接:https://www.haomeiwen.com/subject/noxodttx.html