【掌握】集合类【容器类】 - qingkong1998/ios GitHub Wiki

Foundation

【掌握】集合类【容器类】

字典【理解】

  • 【掌握】概念:字典是一个无序的集合,它使通过键值对的方式来存储数据的
  • 【掌握】特点
    • 一个 key(键) 对应 一个value(值)
    • 做key的元素必须遵守NSCopying
      我们一般使用NSString作为key
  • 【理解】NSDictionary
    • 【掌握】概念:不可变字典,字典创建后里面的元素不可改变
    • 【掌握】创建
      • 通过简介构造方法[【少用】
        • NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@1,@"a",@2,@"b",@3,@"c",nil];
      • 通过初始化方法【少用】
        • [[NSDictionary alloc] initWithObjects:values forKeys:keys];
      • 快捷的创建方法[字面量]【常用】
        • NSDictionary *dict = @{@"a":@1,@"b":@2,@"c":@3};
    • 【掌握】获取字典的长度
      字典中有多个键值对
      • dict.count
      • [dict count]
    • 【掌握】获取某个key对应的元素
      • [dict objectForKey:@"a"];
      • dict[@"a"];
    • 【理解】遍历
      • 【理解】先取出所有的key 或所有的值
        然后通过遍历数组的方式来遍历
        • [dict allKeys]
        • [dict allValues]
      • 【理解】forin[常用]
        •  NSDictionary *dict = @{@"a":@1,@"b":@2,@"c":@3};  
                  
                for (NSString *key in dict) {  
                    NSLog(@"%@-%@",key,dict[key]);  
                }  
          
      • 【理解】block方式[比较常用]
        • [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {

                  NSLog(@"key = %@,value = %@",key,obj);  
                    
              }];  
          
      • 【了解】通过枚举器的方式
        • NSEnumerator * enumer = [dict keyEnumerator];
          NSString *key;
          while (key = [enumer nextObject]) {
          NSLog(@"key = %@,value = %@",key,dict[key]);
          }
        • 取出值的枚举器 [dict objectEnumerator];
    • 字典与文件
      • 写入文件
        • [dict writeToFile:@"/Users/lideshan/Desktop/test.plist" atomically:YES];
      • 从文件中读取
        • [NSDictionary dictionaryWithContentsOfFile:@"/Users/lideshan/Desktop/test.plist"];
  • 【理解】NSMutableDictionary
    • 【掌握】可变字典,继承NSDictionary,可以对其中的元素进行增删改
    • 【掌握】创建
      • [NSMutableDictionary dictionary];
      • [NSMutableDictionary dictionaryWithCapacity:10]
    • 【理解】添加或修改元素
      • [dictM setObject:@4 forKey:@"d"];
      • dictM[@"a"] = @10;
    • 【理解】删除元素
      • 删除某个key对应的键值对
        • [dictM removeObjectForKey:@"a"]
      • 删除数组中所有的key对应的键值对
        • [dictM removeObjectsForKeys:@[@"a",@"b"]];
      • 删除字典中所有元素
        • [dictM removeAllObjects];
    • 【理解】遍历的同时删除元素
      • 字典不支持遍历同时删除元素
      • 可以先通过遍历的方式找出所有要删除的key,放在数组中,然后通过 removeObjectsForKeys:来删除

Set【了解】

  • 特点:无序,元素不可以重复,可以用快速去除数组中的重复元素,效率比数组要高
  • NSSet
    • 特点:不可以变,一经创建不能增删改
    • 创建
      • 通过数组创建
        如数组有重复的元素该方法会去重
        • [NSSet setWithArray:array]
      • [NSSet setWithObjects:@1,@2,@3,nil];
      • 注意:不能通过简便的方式[字面量]创建
    • 判断是否包含某个元素
      • [set containsObject:@1];
    • 遍历
      • forin【 常用】
        • for (NSNumber *num in set) {
          NSLog(@"%@",num);
          }
      • 通过枚举器【少用】
        • NSEnumerator *enumer = [set objectEnumerator];
          NSNumber *number;
          while (number = [enumer nextObject]) {
          NSLog(@"%@",number);
          }
    • NSSet 与 NSArray 之间的转换
      • NSArray 转 NSSet
        • NSSet *set = [NSSet setWithArray:array]
      • NSSet 转 NSArray
        • NSArray *array = [set allObjects];
  • NSMutableSet
    • 特点:可以增删元素
    • 创建
      • [NSMutableSet set];
      • [NSMutableSet setWithCapacity:10];
    • 添加
      • [setM addObject:@1];
    • 删除
      • [setM removeObject:@1];

【掌握】集合类之间的转换

  • NSArray 转 NSMutableArray
    • [NSMutableArray arrayWithArray:array];
  • NSDictionary 转 NSMutableDictionary
    • [NSMutableDictionary dictionaryWithDictionary:dict];
  • NSSet 转 NSMutableSet
    • [NSMutableSet setWithSet:set];
  • NSArray 转 NSSet
    • NSSet *set = [NSSet setWithArray:array];
  • NSSet 转 NSArray
    • NSArray *array = [set allObjects]
  • NSDictionary 转 NSArray
    • NSArray * keys = [dict allKeys];
      NSArray * values = [dict allValues];

【掌握】集合类中的内存管理

  • MRC
    • 当你把一个对象放在集合类中的时候,集合会对这个对象进行一次retain操作
    • 当你把一个对象从集合类移除的时候,集合会对这个对象进行一次
    • 当集合销毁的时候,会对集合类中的所有对象进行一次release的操作
  • ARC
    • 当你把一个对象添加到集合中,集合会对这个对象有一个强引用
    • 当你吧一个对象从集合中移除的时候,集合会释放掉对这个对象的强引用
    • 当集合销毁的时候,会释放掉集合中所有对象的强引用

【掌握】常用结构体

NSRange

  • 表示一个区间
  • location 表示起点
    length 表示长度

NSPoint/CGPoint

  • 表示平面上一个点
  • x 表示x坐标
    y 表示y坐标

NSSize/CGSize

  • 表示尺寸(大小)
  • width 宽
    height 高

NSRect/CGRect

  • 表示平面上的一个区域
  • origin 位置(CGPoint)
    size 尺寸(CGSize)

创建方法【掌握】

  • CGPoint创建
    • CGPointMake(CGFloat x, CGFloat y)
  • CGSize创建
    • CGSizeMake(CGFloat width, CGFloat height)
  • CGRectMake 创建
    • CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)

结构体转字符串【理解】

  • NSRange转字符串
    • NSStringFromRange(NSRange range)
  • NSPoint转字符串
    • NSStringFromPoint(NSPoint aPoint)
  • NSSize转字符串
    • NSStringFromSize(NSSize aSize)
  • NSRect 转字符串
    • NSStringFromRect(NSRect aRect)

【掌握】基本数据类型包装类NSNumber

基本类转包装类型

  • [NSNumber numberWithInt:(int)];
    [NSNumber numberWithChar:(char)];
    [NSNumber numberWithDouble:(double)];
    [NSNumber numberWithFloat:(float)];
    [NSNumber numberWithBool:(BOOL)];

包装类型转基本类型

  • number.intValue;
    number.floatValue;
    number.doubleValue;
    number.charValue;
    number.boolValue

【掌握】 结构体的包装类NSValue

结构体转NSValue

  • 常见结构体转换
    • [NSValue valueWithRange:(NSRange)];
      [NSValue valueWithPoint:(NSPoint)];
      [NSValue valueWithSize:(NSSize)];
      [NSValue valueWithRect:(NSRect)];
  • 自定义结构体转换
    • [NSValue valueWithBytes:(const void *) value objCType:(const char *)] type]
      value 普通的结构体指针
      type @encode(C语言的结构体类型)
    • typedef struct {
      double width;
      double height;
      } MYSize;
      MYSize size = {2,10};
      NSValue *value = [NSValue valueWithBytes:&size objCType:@encode(MYSize)];

NSValue 转结构体

  • 常见结构转换
    • value.rangeValue;
      value.pointValue;
      value.sizeValue;
      value.rectValue;
  • 自定义结构体转换
    • [value getValue:&size];

【理解】 NSDate

【掌握】创建日期

  • NSDate *date = [NSDate date];
    • (instancetype)dateWithTimeIntervalSinceNow:(NSTimeInterval)secs;
  • NSDate *da = [[NSDate alloc] init];
  • NSLog(@"%@",date); 输出的时间是格林威治标准时间
    本初子午线穿过哪里

【掌握】日期格式化

  • // 创建日期
    NSDate *date = [NSDate date];
    // 创建日期格式化器
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    // 设置日期格式
    formatter.dateFormat = @"yyyy年MM月dd日 HH时mm分ss秒 Z";
    // yyyy:年 MM:月 dd:日 hh:时 mm:分 ss:秒 Z代表时区
    // 将日期转换为指定格式的字符串
    NSString *dateStr = [formatter stringFromDate:date];
    NSLog(@"%@",dateStr);
    // 将格式字符串转为日期
    NSDate *newDate = [formatter dateFromString:dateStr];
    NSLog(@"%@",newDate);

【理解】日期比较

  • 判断两个日期是否相同
    •  BOOL isEqual =  [date1 isEqualToDate:date2];  
      
  • 日期比较
    • NSComparisonResult res = [date1 compare:date2];
  • 返回两个日期中较早一个
    • NSDate * earlierDate = [date1 earlierDate:date2];
  • 返回两个日期中较晚的一个
    • NSDate *laterDate = [date1 laterDate:date2];

【理解】NSCalendar

  • 日历:主要用于日期的计算
  • 取出日期的某一部分
    • // 1.当前时间
      NSDate *now = [NSDate date];
      // 2.创建一个日历对象
      NSCalendar *calendar = [NSCalendar currentCalendar];
      // 3.利用日历对象 或者 时间对象 对应的 年、月、日、时分秒
      int unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
      NSDateComponents *cmps = [calendar components:unit fromDate:now];
      // 4.打印时间的要素
      NSLog(@"%ld", cmps.day);
  • 计算两个日期之间相差的时间
    •     NSString *time1 = @"2014-12-08 20:50:40";  
            NSString *time2 = @"2014-12-04 18:45:30";  
              
            NSDateFormatter *fmt = [[NSDateFormatter alloc] init];  
            fmt.dateFormat = @"yyyy-MM-dd HH:mm:ss";  
              
            NSDate *date1 = [fmt dateFromString:time1];  
            NSDate *date2 = [fmt dateFromString:time2];  
              
            // 1.创建一个日历对象  
            NSCalendar *calendar = [NSCalendar currentCalendar];  
              
            // 2.比较时间的差距  
            int unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay  
            | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;  
            NSDateComponents *cmps = [calendar components:unit fromDate:date2 toDate:date1 options:0];  
              
            NSLog(@"相差%ld年%ld月%ld天%ld小时%ld分钟%ld秒", cmps.year, cmps.month, cmps.day, cmps.hour, cmps.minute, cmps.second);  
      
  • 在原来的日期的基础上添加时间
    • NSDate *newDate = [calendar dateByAddingComponents:cmps toDate:date options:NSCalendarMatchStrictly];
  • 获取当前的日历对象
    • NSCalendar *calendar = [NSCalendar currentCalendar];

【理解】文件操作

【理解】文件管理器NSFileManager

  • 概念:该类是一个单例类,用于文件相关的操作
  • 获取文件管理器
    • NSFileManager * defaultManager = [NSFileManager defaultManager];
  • 【理解】判断是该路径下是否存在文件或文件夹
    • BOOL isExist = [fileManager fileExistsAtPath:path];
    • BOOL isDir = NO;
      BOOL isExist = [fileManager fileExistsAtPath:path isDirectory:&isDir];
      如果是目录isDir的值为YES,
      注意:1、这里传入的是一个BOOL类型的变量的地址
      2、只有文件存在才会判断他是路径还是文件,如果路径或文件不存两个值都是NO
  • 【了解】文件权限
    • 判断文件是否可读的
      • BOOL isReadable = [fileManager isReadableFileAtPath:path];
    • 判断文件是否是可写的
      • BOOL isWritable = [fileManager isWritableFileAtPath:path];
  • 【了解】获取文件或目录的属性
    • NSFileManager *fileManager = [NSFileManager defaultManager];
      NSString *path = @"/Users/lideshan/Desktop";
      NSError *error;
      NSDictionary *dict = [fileManager attributesOfItemAtPath:path error:&error];
      NSLog(@"%@",dict);
      NSLog(@"%@",dict[@"NSFileSize"]);//我们可以通过这个属性获取文件的大小
      NSLog(@"%@",dict[NSFileSize]);//与上面的方式是等价的,我们通常使用这一种
  • 【理解】获取目录的内容
    • 获得当前文件夹下的内容
      • NSError *error = nil;
        NSArray *array = [fileManager contentsOfDirectoryAtPath:path error:&error];
    • 获得当前文件夹下及其子文件夹的内容
      • NSError *error = nil;
        NSArray *array = [fileManager subpathsOfDirectoryAtPath:path error:&error];
  • 【理解】拷贝文件(原文件保留)
    • [fileManager copyItemAtPath:src toPath:dest error:&error];
  • 【理解】移动文件(原文件会被删除)
    • [fileManager moveItemAtPath:src toPath:dest error:&error];
  • 【掌握】创建目录
    • [fileManager createDirectoryAtPath:dest withIntermediateDirectories:NO attributes:nil error:&error];
      withIntermediateDirectories:是否要创建中间目录
      YES 表示创建中间目录
      NO 表示不创建中间目录
      attributes: 是目录的属性信息,nil表示使用默认属性
  • 【掌握】创建文件
    • [fileManager createFileAtPath:dest contents:data attributes:nil];

【掌握】NSData

  • 概念: IOS中二进制文件使用NSData保存
    音频、视频文件必须使用NSData来保存
  • 把文件加载到内存
    • NSData *data = [NSData dataWithContentsOfFile:path];
    • 注意:  NSData是不可变的Data类型,只能通过一次加载,完成所有的数据加载
  • 把内存中的数据写入到文件中
    • [data writeToFile:path atomically:YES];

【掌握】NSMutableData

  • 当你需要把多个NSData数据拼接成一个数据存储的时候,就要使用NSMutableData
  • NSMutableData *dataM = [NSMutableData data];
    [dataM appendData:data];

【理解】NSObject

判断某个实例对象是否实现某个方法

    • (BOOL)respondsToSelector:(SEL)aSelector;

让某个实例对象动态去执行某个方法

    • (id)performSelector:(SEL)aSelector;
      • (id)performSelector:(SEL)aSelector withObject:(id)object;
      • (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

判断一个实例对象是否是一个类的实例对象

    • (BOOL)isMemberOfClass:(Class)aClass;

判断一个实例对象是否是一个类 或其子类的实例对象

    • (BOOL)isKindOfClass:(Class)aClass;

判断一个实例对象是否实现了某个协议

    • (BOOL)conformsToProtocol:(Protocol *)aProtocol;

【理解】复制

浅复制

  • 不会产生新对象的复制
  • NSString调用copy : 浅复制
  • 如果是不可变对象调用copy方法产出不可变副本,那么不会产生新的对象

深复制

  • 会产生全新的对象的复制
  • NSString调用mutableCopy : 深复制
  • NSMutableString调用copy : 深复制
  • NSMutableString调用mutableCopy : 深复制
  • 可变对象上调用copy 或 mutableCopy都会产生一个全新的对象,不可变量对象调用 mutableCopy会产生一个新对象

复制与引用计数器

  • 在MRC中,不可变对象调用copy方法,引用计数+1(NSString除外),不可变对象调用mutableCopy会产生一个全新的对象引用计数为1,可变对象调用copy 或 mutableCopy都会产生一个全新的对象,引用计数为1

不可变对象

  • 一经创建不可增加、删除、修改的对象,只要是对对象中内容进行修改添加删除的操作的方法都会返回一个全新的对象,而原来的对象不受影响
  • NSString,NSArray,NSDictionary,NSSet

可变对象

  • 创建后可以进行增删改对象,可以在原来的对象的基础上进行增删改,当一个对象中的元素需要经常进行增删改的操作的时候,使用可变对象效率更高
  • NSMutableString,NSMutableArray,NSMutableDictionary,NSMutableSet