• 08OC之Foundation框架


    1、Foundation框架简述

    在前面,我们创建一个类的时候,都会选择Cocoa Class。到底Cocoa Class是什么东西呢?

    Cocoa 不是一门编程语言,因为它可以运行在多种编程语言上,包含了众多子框架,其中最重要的要数“Foundation”和“UIKit”。前者是框架的基础,和界面无关,其中包含了大量常用的API;后者是基础的UI类库,以后我们在IOS开发中会经常用到。

    其实所有的Mac OS X和IOS程序都是由大量的对象构成,而这些对象的根对象都是NSObject,NSObject就处在Foundation框架之中。

    我们可以把这些对象分为:

    1. 值对象
    2. 集合
    3. 操作系统服务:文件系统、URL、进程通讯
    4. 通知
    5. 归档和序列化
    6. 表达式和条件判断
    7. Objective-C语言服务

    2、常用的结构体

    在Foundation框架中,定义了很多常用的结果来简化我们的日常开发,这些结构体完全采用OC的定义,和我们自己定义的结构体没有任何区别,例如常用的结构体有NSRange、NSPoint、NSSize、NSRect等等。

    3、日期操作

    接下来我们熟悉下OC中的日期操作。

    #import <Foundation/Foundation.h>
    
    
    int main(int argc, const char * argv[]) {
        
        NSDate *date1=[NSDate date];//获得当前日期
        NSLog(@"%@",date1); //结果:2014-07-16 07:25:28 +0000
        
        NSDate *date2=[NSDate dateWithTimeIntervalSinceNow:100];//在当前日期的基础上加上100秒,注意在ObjC中多数时间单位都是秒
        NSLog(@"%@",date2); //结果:2014-07-16 07:27:08 +0000
        
        NSDate *date3=[NSDate distantFuture];//随机获取一个将来的日期
        NSLog(@"%@",date3); //结果:4001-01-01 00:00:00 +0000
        
        NSTimeInterval time=[date2 timeIntervalSinceDate:date1];//日期之差,返回单位为秒
        NSLog(@"%f",time); //结果:100.008833
        
        NSDate *date5=[date1 earlierDate:date3];//返回比较早的日期
        NSLog(@"%@",date5); //结果:2014-07-16 07:25:28 +0000
        
        //日期格式化
        NSDateFormatter *formater1=[[NSDateFormatter alloc]init];
        formater1.dateFormat=@"yy-MM-dd HH:mm:ss";
        NSString *datestr1=[formater1 stringFromDate:date1];
        NSLog(@"%@",datestr1); //结果:14-07-16 15:25:28
        //字符串转化为日期
        NSDate *date6=[formater1 dateFromString:@"14-02-14 11:07:16"];
        NSLog(@"%@",date6); //结果:2014-02-14 03:07:16 +0000
    
        return 0;
    }

    4、字符串操作

    在OC中字符串操作要比在C语言中简单的多,在下面的例子中你将看到字符串的初始化、大小写转化、后缀前缀判断、字符串比较、字符串截取、字符串转换等,通过下面的例子我们基本可以掌握常用的字符串操作(注意这些内容虽然基本,但却是十分常用的操作,需要牢记):

    #import <Foundation/Foundation.h>
    
    /**字符串操作*/
    void test1(){
        char *str1="C string";//这是C语言创建的字符串
        NSString *str2=@"OC string";//ObjC字符串需要加@,并且这种方式创建的对象不需要自己释放内存
    
        //下面的创建方法都应该释放内存
        NSString *str3=[[NSString alloc] init];
        str3=@"OC string";
        NSString *str4=[[NSString alloc] initWithString:@"Objective-C string"];
        NSString *str5=[[NSString alloc] initWithFormat:@"age is %i,name is %.2f",19,1.72f];
        NSString *str6=[[NSString alloc] initWithUTF8String:"C string"];//C语言的字符串转换为ObjC字符串
    
        //以上方法都有对应静态方法(一般以string开头),不需要管理内存(系统静态方法一般都是自动释放)
        NSString *str7=[NSString stringWithString:@"Objective-C string"];
    }
    void test2(){
        NSLog(@""Hello world!" to upper is %@",[@"Hello world!" uppercaseString]);
        //结果:"Hello world!" to upper is HELLO WORLD!
        NSLog(@""Hello world!" to lowwer is %@",[@"Hello world!" lowercaseString]);
        //结果:"Hello world!" to lowwer is hello world!
         
        //首字母大写,其他字母小写
        NSLog(@""Hello world!" to capitalize is %@",[@"Hello world!" capitalizedString]);
        //结果:"Hello world!" to capitalize is Hello World!
         
        BOOL result= [@"abc" isEqualToString:@"aBc"];
        NSLog(@"%i",result);
        //结果:0
        NSComparisonResult result2= [@"abc" compare:@"aBc"];//如果是[@"abc" caseInsensitiveCompare:@"aBc"]则忽略大小写比较
        if(result2==NSOrderedAscending){
            NSLog(@"left<right.");
        }else if(result2==NSOrderedDescending){
            NSLog(@"left>right.");
        }else if(result2==NSOrderedSame){
            NSLog(@"left=right.");
        }
        //结果:left>right.
    }
    void test3(){
        NSLog(@"has prefix ab? %i",[@"abcdef" hasPrefix:@"ab"]);
        //结果:has prefix ab? 1
        NSLog(@"has suffix ab? %i",[@"abcdef" hasSuffix:@"ef"]);
        //结果:has suffix ab? 1
        NSRange range=[@"abcdefabcdef" rangeOfString:@"cde"];//注意如果遇到cde则不再往后面搜索,如果从后面搜索或其他搜索方式可以设置第二个options参数
        if(range.location==NSNotFound){
            NSLog(@"not found.");
        }else{
            NSLog(@"range is %@",NSStringFromRange(range));
        }
        //结果:range is {2, 3}
    }
    //字符串分割
    void test4(){
        NSLog(@"%@",[@"abcdef" substringFromIndex:3]);//从第三个索引开始(包括第三个索引对应的字符)截取到最后一位
        //结果:def
        NSLog(@"%@",[@"abcdef" substringToIndex:3]);////从0开始截取到第三个索引(不包括第三个索引对应的字符)
        //结果:abc
        NSLog(@"%@",[@"abcdef" substringWithRange:NSMakeRange(2, 3)]);
        //结果:cde
        NSString *str1=@"12.abcd.3a";
        NSArray *array1=[str1 componentsSeparatedByString:@"."];//字符串分割
        NSLog(@"%@",array1);
         /*结果:
          (
             12,
             abcd,
             3a
          )
          */
     
    }
    //其他操作
    void test5(){
        NSLog(@"%i",[@"12" intValue]);//类型转换
        //结果:12
        NSLog(@"%zi",[@"hello world,世界你好!" length]);//字符串长度注意不是字节数
        //结果:17
        NSLog(@"%c",[@"abc" characterAtIndex:0]);//取出制定位置的字符
        //结果:a
        const char *s=[@"abc" UTF8String];//转换为C语言字符串
        NSLog(@"%s",s);
        //结果:abc
    }
    
    int main(int argc, const char * argv[]) {
        test1();
        test2();
        test3();
        test4();
        test5();
        return 0;
    }

    注意:上面代码注释中提到的需要释放内存指的是在MRC下的情况,当然本质上在ARC下也需要释放,只是这部分代码编译器会自动创建。

    5、文件操作

    在OC中路径、文件读写等操作是利用字符串来完成的,这里通过几个简单的例子来演示(首先在桌面上新建一个test.txt文件,里面存储的内容是”hello world,世界你好!”)

    #import <Foundation/Foundation.h>
    
    
    void test1(){
        //读取文件内容
        NSString *path=@"/Users/kenshincui/Desktop/test.txt";
        NSString *str1=[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
        //注意上面也可以使用gb2312 gbk等,例如kCFStringEncodingGB_18030_2000,但是需要用CFStringConvertEncodingToNSStringEncoding转换
        NSLog(@"str1 is %@",str1);
        //结果:str1 is hello world,世界你好!
    
        
        
        
        //上面我们看到了读取文件,但并没有处理错误,当然在ObjC中可以@try @catch @finnally但通常我们并不那么做
        //由于我们的test.txt中有中文,所以使用下面的编码读取会报错,下面的代码演示了错误获取的过程
        NSError *error;
        NSString *str2=[NSString stringWithContentsOfFile:path encoding:kCFStringEncodingGB_18030_2000 error:&error];//注意这句话中的error变量是**error,就是指针的指针那就是指针的地址,由于error就是一个指针此处也就是error的地址&error,具体原因见下面补充
        if(error){
            NSLog(@"read error ,the error is %@",error);
        }else{
            NSLog(@"read success,the file content is %@",str2);
        }
        //结果:read error ,the error is Error Domain=NSCocoaErrorDomain Code=261 "The file couldn’t be opened using the specified text encoding." UserInfo=0x100109620 {NSFilePath=/Users/kenshincui/Desktop/test.txt, NSStringEncoding=1586}
    
        
        
        
        //读取文件内容还有一种方式就是利用URl,它除了可以读取本地文件还可以读取网络文件
        //NSURL *url=[NSURL URLWithString:@"file:///Users/kenshincui/Desktop/test.txt"];
        NSURL *url=[NSURL URLWithString:@"http://www.apple.com"];
        NSString *str3=[NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
        NSLog(@"str3 is %@",str3);
    }
    void test2(){
        //下面是文件写入
        NSString *path1=@"/Users/kenshincui/Desktop/test2.txt";
        NSError *error1;
        NSString *str11=@"hello world,世界你好!";
        [str11 writeToFile:path1 atomically:YES encoding:NSUTF8StringEncoding error:&error1];//automically代表一次性写入,如果写到中间出错了最后就全部不写入
        if(error1){
            NSLog(@"write fail,the error is %@",[error1 localizedDescription]);//调用localizedDescription是只打印关键错误信息
        }else{
            NSLog(@"write success!");
        }
        //结果:write success!
    }
    //路径操作
    void test3(){
        NSMutableArray *marray=[NSMutableArray array];//可变数组
        [marray addObject:@"Users"];
        [marray addObject:@"KenshinCui"];
        [marray addObject:@"Desktop"];
    
        NSString *path=[NSString pathWithComponents:marray];
        NSLog(@"%@",path);//字符串拼接成路径
        //结果:Users/KenshinCui/Desktop
    
        NSLog(@"%@",[path pathComponents]);//路径分割成数组
        /*结果: 
         (
            Users,
            KenshinCui,
            Desktop
        )
        */
    
        NSLog(@"%i",[path isAbsolutePath]);//是否绝对路径(其实就是看字符串是否以“/”开头)
        //结果:0
        NSLog(@"%@",[path lastPathComponent]);//取得最后一个目录
        //结果:Desktop
        NSLog(@"%@",[path stringByDeletingLastPathComponent]);//删除最后一个目录,注意path本身是常量不会被修改,只是返回一个新字符串
        //结果:Users/KenshinCui
        NSLog(@"%@",[path stringByAppendingPathComponent:@"Documents"]);//路径拼接
        //结果:Users/KenshinCui/Desktop/Documents
    }
     //扩展名操作
    void test4(){
        NSString *path=@"Users/KenshinCui/Desktop/test.txt";
        NSLog(@"%@",[path pathExtension]);//取得扩展名,注意ObjC中扩展名不包括"."
        //结果:txt
        NSLog(@"%@",[path stringByDeletingPathExtension]);//删除扩展名,注意包含"."
        //结果:Users/KenshinCui/Desktop/test
        NSLog(@"%@",[@"Users/KenshinCui/Desktop/test" stringByAppendingPathExtension:@"mp3"]);//添加扩展名
        //结果:Users/KenshinCui/Desktop/test.mp3
    }
    
    int main(int argc, const char * argv[]) {
        test1();
        test2();
        test3();
        test4();
        return 0;
    }

    6、可变字符串

    我们知道在字符串操作过程中我们经常希望改变原来的字符串,当然这在C语言中实现比较复杂,但是ObjC为我们提供了新的可变字符串类NSMutableString,它是NSString的子类。

    #import <Foundation/Foundation.h>
    
    
    int main(int argc, const char * argv[]) {
        
        /*可变字符串,注意NSMutableString是NSString子类*/
        //注意虽然initWithCapacity分配字符串大小,但是不是绝对的不可以超过此范围,声明此变量对性能有好处
        NSMutableString *str1= [[NSMutableString alloc] initWithCapacity:10];
        [str1 setString:@"hello"];//设置字符串
        NSLog(@"%@",str1);
        //结果:hello
    
        [str1 appendString:@",world!"];//追加字符串
        NSLog(@"%@",str1);
        //结果:hello,world!
    
        [str1 appendFormat:@"我的年龄是%i。dear,I love you.",18];
        NSLog(@"%@",str1);
        //结果:hello,world!我的年龄是18。dear,I love you.
        
        //替换字符串
        NSRange range=[str1 rangeOfString:@"dear"];
        [str1 replaceCharactersInRange:range withString:@"Honey"];
        NSLog(@"%@",str1);
        //结果:hello,world!我的年龄是18。Honey,I love you.
        
        //插入字符串
        [str1 insertString:@"My name is Kenshin." atIndex:12];
        NSLog(@"%@",str1);
        //结果:hello,world!My name is Kenshin.我的年龄是18。Honey,I love you.
        
        //删除指定字符串
        [str1 deleteCharactersInRange:[str1 rangeOfString:@"My name is Kenshin."]];//删除指定范围的字符串
        NSLog(@"%@",str1);
        //结果:hello,world!我的年龄是18。Honey,I love you.
        
        return 0;
    }

    7、数组

    不可变数组

    数组操作:初始化、数组对象的方法执行、数组元素的遍历、在原有数组基础上产生新数组、数组排序等

    #import <Foundation/Foundation.h>
    #import "Person.h"
    
    
    void test1(){
        //NSArray长度不可变所以初始化的时候就赋值,并且最后以nil结尾
        //此外需要注意NSArray不能存放C语言的基础类型
        NSObject *obj=[[NSObject alloc]init];
        //NSArray *array1=[[NSArray alloc] initWithObjects:@"abc",obj,@"cde",@"opq", nil];
        NSArray *array1=[NSArray arrayWithObjects:@"abc",obj,@"cde",@"opq",@25, nil];
        NSLog(@"%zi",array1.count);//数组长度,结果:5
        NSLog(@"%i",[array1 containsObject:@"cde"]);//是否包含某个对象,结果:1
        NSLog(@"%@",[array1 lastObject]);//最后一个对象,结果:25
        NSLog(@"%zi",[array1 indexOfObject:@"abc"]);//对象所在的位置:0
        
        Person *person1=[Person personWithName:@"Kenshin"];
        Person *person2=[Person personWithName:@"Kaoru"];
        Person *person3=[Person personWithName:@"Rosa"];
        NSArray *array2=[[NSArray alloc]initWithObjects:person1,person2,person3, nil];
        [array2 makeObjectsPerformSelector:@selector(showMessage:) withObject:@"Hello,world!"];//执行所有元素的showMessage方法,后面的参数最多只能有一个
        /*结果:
         My name is Kenshin,the infomation is "Hello,world!".
         My name is Kaoru,the infomation is "Hello,world!".
         My name is Rosa,the infomation is "Hello,world!".
         */
    }
    //数组的遍历
    void test2(){
        NSObject *obj=[[NSObject alloc]init];
        NSArray *array=[[NSArray alloc] initWithObjects:@"abc",obj,@"cde",@"opq",@25, nil];
        //方法1
        for(int i=0,len=array.count;i<len;++i){
            NSLog(@"method1:index %i is %@",i,[array objectAtIndex:i]);
        }
        /*结果:
         method1:index 0 is abc
         method1:index 1 is <NSObject: 0x100106de0>
         method1:index 2 is cde
         method1:index 3 is opq
         method1:index 4 is 25
         */
        
        
        //方法2
        for(id obj in array){
            NSLog(@"method2:index %zi is %@",[array indexOfObject:obj],obj);
        }
        /*结果:
         method2:index 0 is abc
         method2:index 1 is <NSObject: 0x100602f00>
         method2:index 2 is cde
         method2:index 3 is opq
         method2:index 4 is 25
         */
        
        
        //方法3,利用代码块方法
        [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            NSLog(@"method3:index %zi is %@",idx,obj);
            if(idx==2){//当idx=2时设置*stop为YES停止遍历
                *stop=YES;
            }
        }];
        /*结果:
         method3:index 0 is abc
         method3:index 1 is <NSObject: 0x100106de0>
         method3:index 2 is cde
         */
        
        
        //方法4,利用迭代器
        //NSEnumerator *enumerator= [array objectEnumerator];//获得一个迭代器
        NSEnumerator *enumerator=[array reverseObjectEnumerator];//获取一个反向迭代器
        //NSLog(@"all:%@",[enumerator allObjects]);//获取所有迭代对象,注意调用完此方法迭代器就遍历完了,下面的nextObject就没有值了
        id obj2=nil;
        while (obj2=[enumerator nextObject]) {
            NSLog(@"method4:%@",obj2);
        }
        /*结果:
         method4:25
         method4:opq
         method4:cde
         method4:<NSObject: 0x100106de0>
         method4:abc
         */
    }
    //数组派生出新的数组
    void test3(){
        NSArray *array=[NSArray arrayWithObjects:@"1",@"2",@"3", nil];
        NSArray *array2=[array arrayByAddingObject:@"4"];//注意此时array并没有变
        NSLog(@"%@",array2);
        /*结果:
         (
             1,
             2,
             3,
             4
         )
         */
        
        
        NSLog(@"%@",[array2 arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@"5",@"6", nil]]);//追加形成新的数组
        /*结果:
         (
             1,
             2,
             3,
             4,
             5,
             6
         )
         */
        
        
        NSLog(@"%@",[array2 subarrayWithRange:NSMakeRange(1, 3)]);//根据一定范围取得生成一个新的数组
        /*结果:
         (
             2,
             3,
             4
         )
         */
        
        
        NSLog(@"%@",[array componentsJoinedByString:@","]);//数组连接,形成一个字符串
        //结果:1,2,3
        
        //读写文件
        NSString *path=@"/Users/KenshinCui/Desktop/array.xml";
        [array writeToFile:path atomically:YES];
        NSArray *array3=[NSArray arrayWithContentsOfFile:path];
        NSLog(@"%@",array3);
        /*结果:
         (
             1,
             2,
             3
         )
         */
    }
    //数组排序
    void test4(){
        //方法1,使用自带的比较器
        NSArray *array=[NSArray arrayWithObjects:@"3",@"1",@"2", nil];
        NSArray *array2= [array sortedArrayUsingSelector:@selector(compare:)];
        NSLog(@"%@",array2);
        /*结果:
         (
             1,
             2,
             3
         )
         */
        
        
        //方法2,自己定义比较器
        Person *person1=[Person personWithName:@"Kenshin"];
        Person *person2=[Person personWithName:@"Kaoru"];
        Person *person3=[Person personWithName:@"Rosa"];
        NSArray *array3=[NSArray arrayWithObjects:person1,person2,person3, nil];
        NSArray *array4=[array3 sortedArrayUsingSelector:@selector(comparePerson:)];
        NSLog(@"%@",array4);
        /*结果:
         (
             "name=Kaoru",
             "name=Kenshin",
             "name=Rosa"
         )
         */
        
        
        //方法3使用代码块
        NSArray *array5=[array3 sortedArrayUsingComparator:^NSComparisonResult(Person *obj1, Person *obj2) {
            return [obj2.name compare:obj1.name];//降序
        }];
        NSLog(@"%@",array5);
        /*结果:
         (
             "name=Rosa",
             "name=Kenshin",
             "name=Kaoru"
         )
         */
        
        
        //方法4 通过描述器定义排序规则
        Person *person4=[Person personWithName:@"Jack"];
        Person *person5=[Person personWithName:@"Jerry"];
        Person *person6=[Person personWithName:@"Tom"];
        Person *person7=[Person personWithName:@"Terry"];
        NSArray *array6=[NSArray arrayWithObjects:person4,person5,person6,person7, nil];
        //定义一个排序描述
        NSSortDescriptor *personName=[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
        NSSortDescriptor *accountBalance=[NSSortDescriptor sortDescriptorWithKey:@"account.balance" ascending:YES];
        NSArray *des=[NSArray arrayWithObjects:personName,accountBalance, nil];//先按照person的name排序再按照account的balance排序
        NSArray *array7=[array6 sortedArrayUsingDescriptors:des];
        NSLog(@"%@",array7);
        /*结果:
         (
             "name=Jack",
             "name=Jerry",
             "name=Terry",
             "name=Tom"
         )
         */
    }
    
    int main(int argc, const char * argv[]) {
        test1();
        test2();
        test3();
        test4();
        return 0;
    }

    需要注意的是:

    • NSArray中只能存放对象,不能存放基本数据类型,通常我们可以通过在基本数据类型前加@进行转换;
    • 数组中的元素后面必须加nil以表示数据结束;
    • makeObjectsPerformSelector执行数组中对象的方法,其参数最多只能有一个;
    • 上面数组操作中无论是数组的追加、删除、截取都没有改变原来的数组,只是产生了新的数组而已;
    • 对象的比较除了使用系统自带的方法,我们可以通过自定义比较器的方法来实现;

    可变数组:

    #import <Foundation/Foundation.h>
    #import "Person.h"
    
    
    void test1(){
        Person *person1=[Person personWithName:@"Kenshin"];
        Person *person2=[Person personWithName:@"Kaoru"];
        Person *person3=[Person personWithName:@"Rosa"];
        NSMutableArray *array1=[NSMutableArray arrayWithObjects:person1,person2,person3, nil];
        NSLog(@"%@",array1);
        /*结果:
         (
             "name=Kenshin",
             "name=Kaoru",
             "name=Rosa"
         )
         */
        
        Person *person4=[Person personWithName:@"Jack"];//此时person4的retainCount为1
        [array1 addObject:person4];//添加一个元素,此时person4的retainCount为2
        NSLog(@"%@",array1);
        /*结果:
         (
             "name=Kenshin",
             "name=Kaoru",
             "name=Rosa",
             "name=Jack"
         )
         */
        
        [array1 removeObject:person3];//删除一个元素
        NSLog(@"%@",array1);
        /*结果:
         (
             "name=Kenshin",
             "name=Kaoru",
             "name=Jack"
         )
         */
        
        [array1 removeLastObject];//删除最后一个元素,//此时person4的retainCount为1
        NSLog(@"%@",array1);
        /*结果:
         (
             "name=Kenshin",
             "name=Kaoru"
         )
         */
        
        [array1 removeAllObjects];//删除所以元素
        
        //注意当往数组中添加一个元素时会retain因此计数器+1,当从数组中移除一个元素时会release因此计数器-1
        //当NSMutalbeArray对象release的时候会依次调用每一个对象的release
    }
    void test2(){
        NSMutableArray *array1=[NSMutableArray arrayWithObjects:@"1",@"3",@"2", nil];
        NSLog(@"%@",array1);
        /*结果:
         (
             1,
             3,
             2
         )
         */
        
        NSArray *array2= [array1 sortedArrayUsingSelector:@selector(compare:)];//注意这个方法没有修改array1
        NSLog(@"%@",array1);
        /*结果:
         (
             1,
             3,
             2
         )
         */
        
        NSLog(@"%@",array2);
        /*结果:
         (
             1,
             2,
             3
         )
         */
        [array1 sortUsingSelector:@selector(compare:)];//这个方法会修改array1
        NSLog(@"%@",array1);
        /*结果:
         (
             1,
             2,
             3
         )
         */
        
    }
    
    int main(int argc, const char * argv[]) {
        
        test1();
        
        test2();
        
        return 0;
    }

    注意:

    • 可变数组中的元素后面必须加nil以表示数据结束;
    • 往一个可变数组中添加一个对象,此时这个对象的引用计数器会加1,当这个对象从可变数组中移除其引用计数器减1。同时当整个数组销毁之后会依次调用每个对象的releaes方法。
    • 在不可变数组中无论对数组怎么排序,原来的数组顺序都不会改变,但是在可变数组中如果使用sortUsingSelector:排序原来的数组顺序就发生了变化。

    8、字典

    字典在我们日常开发中也是比较常用的,通过下面的代码我们看一下在OC中的字典的常用操作:初始化、遍历、排序

    #import <Foundation/Foundation.h>
    
    
    void test1(){
        NSDictionary *dic1=[NSDictionary dictionaryWithObject:@"1" forKey:@"a"];
        NSLog(@"%@",dic1);
        /*结果:
         {
            a = 1;
         }
         */
        
        //常用的方式
        NSDictionary *dic2=[NSDictionary dictionaryWithObjectsAndKeys:
                            @"1",@"a",
                            @"2",@"b",
                            @"3",@"c",
                            nil];
        NSLog(@"%@",dic2);
        /*结果:
         {
             a = 1;
             b = 2;
             c = 3;
         }
         */
        
        
        NSDictionary *dic3=[NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1",@"2", nil] forKeys:[NSArray arrayWithObjects:@"a",@"b", nil]];
        NSLog(@"%@",dic3);
        /*结果:
         {
             a = 1;
             b = 2;
         }
         */
        
        
        //更简单的方式
        NSDictionary *dic4=@{@"1":@"a",@"2":@"b",@"3":@"c"};
        NSLog(@"%@",dic4);
        /*结果:
         {
             1 = a;
             2 = b;
             3 = c;
         }
         */
    }
    void test2(){
        NSDictionary *dic1=[NSDictionary dictionaryWithObjectsAndKeys:
                            @"1",@"a",
                            @"2",@"b",
                            @"3",@"c",
                            @"2",@"d",
                            nil];
        NSLog(@"%zi",[dic1 count]); //结果:4
        NSLog(@"%@",[dic1 valueForKey:@"b"]);//根据键取得值,结果:2
        NSLog(@"%@",dic1[@"b"]);//还可以这样读取,结果:2
        NSLog(@"%@,%@",[dic1 allKeys],[dic1 allValues]);
        /*结果:
         (
             d,
             b,
             c,
             a
         ),(
             2,
             2,
             3,
             1
         )
    
         */
        
        NSLog(@"%@",[dic1 objectsForKeys:[NSArray arrayWithObjects:@"a",@"e" , nil]notFoundMarker:@"not fount"]);//后面一个参数notFoundMarker是如果找不到对应的key用什么值代替
        /*结果:
         (
             1,
             "not fount"
         )
         */
    }
    void test3(){
        NSDictionary *dic1=[NSDictionary dictionaryWithObjectsAndKeys:
                            @"1",@"a",
                            @"2",@"b",
                            @"3",@"c",
                            @"2",@"d",
                            nil];
        //遍历1
        for (id key in dic1) {//注意对于字典for遍历循环的是key
            NSLog(@"%@=%@",key,[dic1 objectForKey:key]);
        }
        /*结果:
         d=2
         b=2
         c=3
         a=1
         */
        
        //遍历2
        NSEnumerator *enumerator=[dic1 keyEnumerator];//还有值的迭代器[dic1 objectEnumerator]
        id key=nil;
        while (key=[enumerator nextObject]) {
            NSLog(@"%@=%@",key,[dic1 objectForKey:key]);
            
        }
        /*结果:
         d=2
         b=2
         c=3
         a=1
         */
        
        //遍历3
        [dic1 enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
            NSLog(@"%@=%@",key,obj);
        }];
        /*结果:
         d=2
         b=2
         c=3
         a=1
         */
    }
    
    void test4(){
        NSMutableDictionary *dic=[NSMutableDictionary dictionaryWithObjectsAndKeys:@"1",@"a",
                                  @"2",@"b",
                                  @"3",@"c",
                                  @"2",@"d",
                                nil];
        [dic removeObjectForKey:@"b"];
        NSLog(@"%@",dic);
        /*结果:
         {
             a = 1;
             c = 3;
             d = 2;
         }
         */
        
        [dic addEntriesFromDictionary:@{@"e":@"7",@"f":@"6"}];
        NSLog(@"%@",dic);
        /*结果:
         {
             a = 1;
             c = 3;
             d = 2;
             e = 7;
             f = 6;
         }
         */
        
        [dic setValue:@"5" forKey:@"a"];
        NSLog(@"%@",dic);
        /*结果:
         {
             a = 5;
             c = 3;
             d = 2;
             e = 7;
             f = 6;
         }
         */
         
        
        //注意,一个字典的key或value添加到字典中时计数器+1;字典释放时调用key或value的release一次,计数器-1
    }
    
    
    int main(int argc, const char * argv[]) {
        test1();
        test2();
        test3();
        test4();
        return 0;
    }

    注意:同数组一样,不管是可变字典还是不可变字典初始化元素后面必须加上nil以表示结束。

    9、装箱和拆箱

  • 相关阅读:
    数据库操作类
    并查集的使用
    简单的图片识别,源代码
    Sql Server清理缓存代码
    京东商城商品价格获取方法
    【转】 SEO的含义与意义
    隐藏控制台窗口的方法
    MySQL存储过程详解
    常见电商B2C网站购物车的设计
    UML建模之业务处理模型(Business Process Model,BPM)
  • 原文地址:https://www.cnblogs.com/duyao/p/4932026.html
Copyright © 2020-2023  润新知