zoukankan      html  css  js  c++  java
  • 一个java程序员自学IOS开发之路(二)

    2015/9/28

    Day 8

    最近工作上比较忙,加上虚拟机里macXcode起来电脑就很卡了,更别提在虚拟机的mac系统里再开iPhone虚拟机了。

    另外乘着中秋国庆好好休息下~过后准备大出血入手Macbook pro

    PS:同事居然在公司发的月饼里吃出来虫子= =,幸好我没打算吃,因为我讨厌月饼

     

    2015/10/1

    Day 9

    开始学习OC内存管理

    OC中的内存是要程序员来管的,因为并没有Java中的垃圾回收机制。

    及时释放内存是我们要时刻考虑的,同时还是注意野指针

    堆空间的对象需要手动代码释放

     

    1)每个OC对象都有自己的 引用计数器 ,它是一个整数(4字节),表示对象被引用的次数,即有多少人在使用此对象

    2)每个OC对象内部都有4个字节的存储空间来储存引用计数器

    3)引用计数器的作用

        a)当使用allocnew或者copy创建一个新对象时,新对象的引用计数器默认就是1

        b)当一个对象的引用计数器的值为0时,该对象占用的内存就会被系统回收

    4)引用计数器的操作

        a)给对象发送一条retain消息,对象的引用计数器的值+1,另外,retain方法返回对象本身

        b)给对象发送一条release消息,对象的引用计数器的值-1

        c)给对象发送一条retainCount消息,获得当前的引用计数器的值

    5)对象的销毁

        a)当一个对象的引用计数器为0的时候,它将被销毁,其占用的内存会被回收

        b)当一个对象被销毁时,系统会自动向对象发送一条dealloc消息

        c)一般会重写dealloc方法,在这里释放相关资源

        d)一旦重写dealloc方法,就必须调用[super dealloc]方法,并且放在最后面调用

        e)不要直接调用dealloc方法

    野指针:指向僵尸对象(不可用内存)的指针

    报错:EXC_BAD_ACCESS  //访问一块坏内存

    释放野指针: p = nil; p变成空指针

    OC中没有Java里臭名昭著的空指针异常~,在OC里用空指针调用任何方法都没事

     

    总结:

    只要有一个alloc,就要有一个release

    只要有一个retain,就要有一个release

    有加就有减~做人要负责!

     

    2015/10/2

    Day 10

    1)原则分析

        a)只要有人使用某个对象,该对象就不会被回收

        b)只要你想用这个对象,就让对象的计数器+1

        c)当你不再使用这个对象,就让对象的计数器-1

    2)谁创建,谁release

    3)谁retain,谁就release

    4)总结

        a)有始有终,有加有减

        b)曾经让对象的计数器+1,必须在最后-1

     

    2015/10/5

    Day 11

    今天是我22周岁生日,多学点知识就当给自己的礼物了

     

    内存管理管的事对象,基本数据类型不需要管

    原则:

    1)只要调用alloc,就必须有relea或者autorelease

    2set方法代码规范

        a)基本数据类型--直接赋值

    - (void)setAge:(int)age {

        _age = age;

    }

        bOC对象类型

    - (void)setCar:(Car *)car {

        if(car != _car) {

            [_car release];

            _car = [car retain];

        }

    }

    3dealloc方法代码规范

        a)一定要有[super dealloc],而且要放在最后

        b)对当前对象所用的其他对象释放

    ex:

    - (void) dealloc {

        [_car release];

        [super dealloc];

    }

     

    4property参数,好用又强大!

        a)内存管理相关

            1.retainrelease旧值,retain新值,适用于OC对象类型

            2.assign:直接赋值,默认如此

            3.copyrelease旧值,copy新值

        b)是否生产setget方法有关

            1.readwrite:同时生成setget方法

            2.readonly:只生成get方法

            3.writeonly:只生成setff

        c)多线程管理相关

            1.nonatomic:不要加线程锁--性能高,大部分情况用它

            2.atomic:加线程锁,默认如此--性能低

        d)定制setget方法名称相关

            1.getter = xxx

            2.setter = xxx:

        一般用于bool类型 exgetter = isRich

     

    类之间的相互调用不用#import引用,用@class导入类 (.h文件,也就是声明文件中)

    @class仅仅是告诉编译器某某东西是个类,如果需要导入其中的成员和方法时,还是要用#import导入

    解决方案:一端用retain,一端用release

     

    5autorelease

        aautorelease方法返回对象本身

        bautorelease会将对象放到一个自动释放池中,当自动释放池被销毁时,会对池里的所有对象做一次release

    自动释放吃的创建

    @autoreleasepool{

        

    }

     

    6IOS程序运行过程中,会创建无数个池子,这些池子都是以栈结构存在,当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池

    autorelease用于类方法,比较方便

     

    7ARC机制(Automatic Reference Counting

    他是编译器特性,在编译的时候系统自动给你添加内存管理代码,不是Java中的垃圾回收,在程序运行时,回收内存

     

    ARC的判断准则:没有强指针指的对象就释放

    强指针:默认情况下,所有指针都是强指针

    弱指针:前面加__weak关键字,它不决定对象是否释放

     

    ARC特点

    a)不允许调用releaseretainretainCount

    b)允许重写dealloc,但不允许调用 [super dealloc],因为这些代码ARC会自动生成

    cproperty参数中,对象不要使用retain/assign,取而代之为strong/weak

     

    2015/10/6

    Day 12

    Block数据类型

    1block封装了一段代码,可以在任何时候执行

    2block可以作为函数参数或者函数的返回值,其本身也像函数一样可以带参数以及返回值,个人感觉类似于Java中的匿名函数

    3)建议多使用block

    ex int (^sumblock)(int,int) = ^(int a, int b){

                                        return a+b;

                                     };

    4block内部可以访问外面的变量

    5)默认情况下,block不能修改外面的局部变量,但是如果各局部变量加上__block关键字后,这个变量就可以在block中修改

     

    SEL 数据类型

    它是用来包装函数的,把函数包装成SEL类型的变量

    ex

        SEL s = @selector(函数名)//这样就把该函数包装起来了

        [对象 performSelector:s]//调用该方法

     

    协议 protocol //相当于Java中的接口 interface

    @protocol <#protocol name#> <NSObject>

     

    <#methods#>

     

    @end

    其中的方法,@required(此为默认)表示必须要被实现的方法,如果不实现,编译器会报错

                @optional表示可选方法

    协议也可以遵守协议,基协议<NSObject>

    个人感觉以上都很好接受

     

    分类/类别(Category//OC中特有的语法,依赖于类

    类别(Category)是一种可以为现有的类(包括类簇:NSString...,甚至源码无法获得的类)添加新方法的方式无需从现有的类继承子类。类别添加的新方法可以被子类继承。

    声明类别

    类别的声明和类的声明格式相似:

    @interface ClassName(CategoryName)

    //方法声明

    @end

     

    头文件"NSString+Tools.h"

      #import <Cocoa/Cocoa.h>

      @interface NSString (Tools)

      - (NSNumber *) lengthAsNumber;

      @end//Tools

    实现类别

    实现文件"NSString+Tools.m"

      #import "NSString+Tools.h"

      @implementation NSString(Tools)

      - (NSNumber *) lengthAsNumber

      {

           unsigned int length = [self length];

        return [NSNumber numberWithUnsignedInt: length];

          }

      @end//Tools

    注意

    1)类别不能添加实例变量,只能添加方法

    2)类别里可以访问原来类的成员变量

    3)类别里可以重写原来类中的方法,但要注意这是覆盖!

    4)方法调用的优先级:类别>原来的类>父类,若有多个类别,最后编译的优先

    5)大多情况是给系统/框架自带的类添加类别

    6)可以有无限个类别对原有类进行扩充,一般按照功能分为不同的模块

     

    类扩展Class extensions

    类扩展声明格式:@interface MyClass(), 可以在类扩展中声明属性和实例变量。

    @interface MyClass : NSObject

    ...................

    @end

     

    @interface MyClass()//类扩展

    {

        float _value;

    }

    @property(assign,readonly) value;

    @end

    类扩展就像匿名(也就是没有那个括号里面的名字)的分类/类别一样,除了一样不同的是,类扩展声明必须在@implementation在实现。

     

    2015/10/9

    Day 13

    #import <Foundation/Foundation.h>

    学习Fundation框架其中一些基础的结构体和类

    1NSRange

    NSRange rg = {3,5};//第一参数是起始位置第二个参数是长度

    //NSRange rg;

    //rg.location=3;

    //rg.length=5;

    //NSRange rg={.location=3,.length=5};

    //常用下面的方式定义

    NSRange rg2 = NSMakeRange(3,5);//使用NSMakeRange定义一个NSRange

    //打印NSRange可以使用Foundation中方法 NSLog(@"rg2 is %@", NSStringFromRange(rg2));

    //注意不能直接NSLog(@"rg2 is %@", rg2),因为rg2不是对象(准确的说%@是指针)而是结构体

    2NSPoint/CGPoint

    NSPoint p=NSMakePoint(10, 15);//NSPoint其实就是CGPoint,多用CGPoint,因为它是跨平台的

    //这种方式比较常见 NSPoint p2=CGPointMake(10, 15);

    NSLog(NSStringFromPoint(p2));

    3NSSize/CGSize

    NSSize s=NSMakeSize(10, 15);//NSSize其实就是CGSize

    //这种方式比较常见 CGSize s2=CGSizeMake(10, 15);

    NSLog(NSStringFromSize(s2));

    4NSRect/CGRect

    NSRect r=NSMakeRect(10, 5, 100, 200);//NSRect其实就是CGRect

    //这种方式比较常见 NSRect r2=CGRectMake(10, 5, 100, 200);

    NSLog(NSStringFromRect(r2));

    以上为结构体

    5NSDate

    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

     

    6NSString

    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"];

     

    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.

     

    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}

     

    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);

     

    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

     

    //读取文件内容

    NSString *path=@"/Users/yu3/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/yu3/Desktop/test.txt, NSStringEncoding=1586}

     

    //读取文件内容还有一种方式就是利用URl,它除了可以读取本地文件还可以读取网络文件

    //NSURL *url=[NSURL URLWithString:@"file:///Users/yu3/Desktop/test.txt"];

    NSURL *url=[NSURL URLWithString:@"http://www.apple.com"];

    NSString *str3=[NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];

    NSLog(@"str3 is %@",str3);

     

    //下面是文件写入

    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!

     

    NSMutableArray *marray=[NSMutableArray array];//可变数组

    [marray addObject:@"Users"];

    [marray addObject:@"yu3"];

    [marray addObject:@"Desktop"];

     

    NSString *path=[NSString pathWithComponents:marray];

    NSLog(@"%@",path);//字符串拼接成路径

    //结果:Users/yu3/Desktop

     

    NSLog(@"%@",[path pathComponents]);//路径分割成数组

     

    NSLog(@"%i",[path isAbsolutePath]);//是否绝对路径(其实就是看字符串是否以“/”开头)

    //结果:0

    NSLog(@"%@",[path lastPathComponent]);//取得最后一个目录

    //结果:Desktop

    NSLog(@"%@",[path stringByDeletingLastPathComponent]);//删除最后一个目录,注意path本身是常量不会被修改,只是返回一个新字符串

    //结果:Users/KenshinCui

    NSLog(@"%@",[path stringByAppendingPathComponent:@"Documents"]);//路径拼接

    //结果:Users/KenshinCui/Desktop/Documents

    //拓展名操作

    NSString *path=@"Users/KenshinCui/yu3/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

     

    7)NSMutableString

    /*可变字符串,注意NSMutableStringNSString子类*/

    //注意虽然initWithCapacity分配字符串大小,但是不是绝对的不可以超过此范围,声明此变量对性能有好处

    NSMutableString *str1= [[NSMutableString alloc] initWithCapacity:10];

    [str1 setString:@"hello"];//设置字符串

    NSLog(@"%@",str1);

    //结果:hello

     

    [str1 appendString:@",world!"];//追加字符串

    NSLog(@"%@",str1);

    //结果:hello,world!

     

    [str1 appendFormat:@"我的年龄是%idear,I love you.",18];

    NSLog(@"%@",str1);

    //结果:hello,world!我的年龄是18dear,I love you.

     

    //替换字符串

    NSRange range=[str1 rangeOfString:@"dear"];

    [str1 replaceCharactersInRange:range withString:@"Honey"];

    NSLog(@"%@",str1);

    //结果:hello,world!我的年龄是18Honey,I love you.

     

    //插入字符串

    [str1 insertString:@"My name is yu3." atIndex:12];

    NSLog(@"%@",str1);

    //结果:hello,world!My name is yu3.我的年龄是18Honey,I love you.

     

    //删除指定字符串

    [str1 deleteCharactersInRange:[str1 rangeOfString:@"My name is yu3."]];//删除指定范围的字符串

    NSLog(@"%@",str1);

    //结果:hello,world!我的年龄是18Honey,I love you.

     

    8NSArray

    //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!".

     */

    //数组的遍历

    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]);

    }

    //方法2

    for(id obj in array){

            NSLog(@"method2:index %zi is %@",[array indexOfObject:obj],obj);

    }

    //方法3,利用代码块方法

    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        NSLog(@"method3:index %zi is %@",idx,obj);

        if(idx==2){//idx=2时设置*stopYES停止遍历

            *stop=YES;

        }

    }];

    //方法4,利用迭代器

    //NSEnumerator *enumerator= [array objectEnumerator];//获得一个迭代器

    NSEnumerator *enumerator=[array reverseObjectEnumerator];//获取一个反向迭代器

    //NSLog(@"all:%@",[enumerator allObjects]);//获取所有迭代对象,注意调用完此方法迭代器就遍历完了,下面的nextObject就没有值了

    id obj2=nil;

    while (obj2=[enumerator nextObject]) {

        NSLog(@"method4:%@",obj2);

    }

    NSArray *array=[NSArray arrayWithObjects:@"1",@"2",@"3", nil];

    NSArray *array2=[array arrayByAddingObject:@"4"];//注意此时array并没有变

    NSLog(@"%@",[array2 subarrayWithRange:NSMakeRange(1, 3)]);//根据一定范围取得生成一个新的数组

    NSLog(@"%@",[array componentsJoinedByString:@","]);//数组连接,形成一个字符串

    //读写文件

    NSString *path=@"/Users/yu3/Desktop/array.xml";

    [array writeToFile:path atomically:YES];

    NSArray *array3=[NSArray arrayWithContentsOfFile:path];

    NSLog(@"%@",array3);

     

    //数组排序

    //方法1,使用自带的比较器

    NSArray *array=[NSArray arrayWithObjects:@"3",@"1",@"2", nil];

    NSArray *array2= [array sortedArrayUsingSelector:@selector(compare:)];

    NSLog(@"%@",array2);

    //方法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);

    //方法3使用代码块

    NSArray *array5=[array3 sortedArrayUsingComparator:^NSComparisonResult(Person *obj1, Person *obj2) {

        return [obj2.name compare:obj1.name];//降序

    }];

    NSLog(@"%@",array5);

    //方法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];//先按照personname排序再按照accountbalance排序

    NSArray *array7=[array6 sortedArrayUsingDescriptors:des];

    NSLog(@"%@",array7);

     

    需要注意几点:

    NSArray中只能存放对象,不能存放基本数据类型,通常我们可以通过在基本数据类型前加@进行转换;

    数组中的元素后面必须加nil以表示数据结束;

    makeObjectsPerformSelector执行数组中对象的方法,其参数最多只能有一个;

    上面数组操作中无论是数组的追加、删除、截取都没有改变原来的数组,只是产生了新的数组而已;

    对象的比较除了使用系统自带的方法,我们可以通过自定义比较器的方法来实现;

     

    9)NSMutableArray

    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);

    Person *person4=[Person personWithName:@"Jack"];//此时person4retainCount1

    [array1 addObject:person4];//添加一个元素,此时person4retainCount2

    NSLog(@"%@",array1);

    [array1 removeObject:person3];//删除一个元素

    [array1 removeLastObject];//删除最后一个元素,//此时person4retainCount1

    [array1 removeAllObjects];//删除所以元素

     

    //注意当往数组中添加一个元素时会retain因此计数器+1,当从数组中移除一个元素时会release因此计数器-1

    //NSMutalbeArray对象release的时候会依次调用每一个对象的release

     

    10NSDictionary

    NSDictionary *dic1=[NSDictionary dictionaryWithObject:@"1" forKey:@"a"];

    NSLog(@"%@",dic1);

     

    NSDictionary *dic2=[NSDictionary dictionaryWithObjectsAndKeys:

                        @"1",@"a",

                        @"2",@"b",

                        @"3",@"c",

                        nil];

    NSLog(@"%@",dic2);

     

    NSDictionary *dic3=[NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1",@"2", nil] forKeys:[NSArray arrayWithObjects:@"a",@"b", nil]];

    NSLog(@"%@",dic3);

     

    //更简单的方式

    NSDictionary *dic4=@{@"1":@"a",@"2":@"b",@"3":@"c"};

    NSLog(@"%@",dic4);

     

    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]);

     

    NSLog(@"%@",[dic1 objectsForKeys:[NSArray arrayWithObjects:@"a",@"e" , nil]notFoundMarker:@"not fount"]);//后面一个参数notFoundMarker是如果找不到对应的key用什么值代替

     

    //遍历1

    for (id key in dic1) {//注意对于字典for遍历循环的是key

        NSLog(@"%@=%@",key,[dic1 objectForKey:key]);

    }

    //遍历2

    NSEnumerator *enumerator=[dic1 keyEnumerator];//还有值的迭代器[dic1 objectEnumerator]

    id key=nil;

    while (key=[enumerator nextObject]) {

        NSLog(@"%@=%@",key,[dic1 objectForKey:key]);

        

    }

    [dic1 enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {

        NSLog(@"%@=%@",key,obj);

    }];

    NSMutableDictionary *dic=[NSMutableDictionary dictionaryWithObjectsAndKeys:@"1",@"a",

                              @"2",@"b",

                              @"3",@"c",

                              @"2",@"d",

                              nil];

    [dic removeObjectForKey:@"b"];

    [dic addEntriesFromDictionary:@{@"e":@"7",@"f":@"6"}];

    [dic setValue:@"5" forKey:@"a"];

     

     

     

     

     

     

  • 相关阅读:
    冲刺第一天
    就用户界面和体验评价搜狗输入法
    学习进度条10
    典型用户及用户场景描述
    学习进度条09
    冲刺阶段第八天
    对石家庄铁道大学网站的UI分析
    学习进度条(第八周)
    冲刺阶段第七天
    冲刺阶段第六天
  • 原文地址:https://www.cnblogs.com/yu3-/p/4909363.html
Copyright © 2011-2022 走看看