首页 > 代码库 > block的用法和数组排序(高级)

block的用法和数组排序(高级)

block的用法和数排序()

, block

都知道函数只可以嵌套,但决不允函数的嵌套定,时给们带来了很大的不便,OC提供的block用法解决了问题,下面简单说一下1,block的用法:

(1)block是用来存函数,所以block赋值时赋的是整个函数的实现,例如,要在main函数里写一个求两个数的和的函数,返回值为整型,参数两个整型,通常在函数外面会这样

int sum(int x, int y)

{

    return x + y;

}

如果要在函数内部写就需要用到block句写法如下:

int (^sum)(int x,int y) = ^(int x, int y)

        {

            return x + y;

        };

 

         block 变量的类型是: int (^)(int x,int y) (这里的”(^)”是系统规定的block写法) sumblock变量的名字, "="号右边的

         ^(int x, int y)

        {

            return x + y;

        };

 block变量的初始值,

         当把函数的实现赋给block,block变量sum就可以当做函数名使用

如: NSLog(@"sum = %d",sum (5,10));

block的定可以看出它跟函数指的定很相似,唯一不同就是函数指针的类型定义时是用(*),block是用(^).

(2),此外当在block外面定(局部),如果没有在量前加上"__block",block内部无法对该变量修改,block内部系统识别该变量是readonly不可修改的,如果要修改block,该变量用"__block".block外部的局部量被"__block"后在block内部告诉编译器不要再把该变量当做常量来看待,但是若在block内部访问全局,不需要用__block饰,有关全局变量下面可以再详细的叙述一下;

 

 (3), 如果使用block时对它的定义感觉麻烦,我们也可以使用typedef对它的类型重定义 如: typedefint(^BLOCK) (int x, int y);这样如果再定义该类型的block,只需要使用BLOCK代替int (^)(int x,int y)即可.

 

 (4), 对于全局变量:在一个文件里定义了一个全局变量例如:(int a = 10;),如果在其他文件里想用该变量a(如果在main函数里也定义了int a,则编译时会失,统编译.m文件,main函数也是.m文件,在同.m文件里同两个量名相同的,是不允),则需要在要调用该变量的文件里声明一下即用 externint a;他会告诉编译器,这个变量a已经在其他文件里定义了. 如果在每个文件了都定义了同一个名的变量,又只想在本文件里使用,需要给变量声明为static即定义为静态变量(此时系统识别变量是以static int去找到地址取出其中的数据的).

 

二,     数组排序

 

1,首先建立一个人类   

在.h文件里定义实例变量和方法声明

{

       

        NSString *_name; //姓名

        CGFloat _height; //身高

        NSInteger _age; //年龄

    }

 

//初始化

- (id)initWithname:(NSString *)name age:(NSInteger)age height:(CGFloat)height;

 

//setter

- (void)setName:(NSString *)name;

 

- (void)setHeight:(CGFloat)height;

 

- (void)setAge:(NSInteger)age;

 

 

//getter

 

- (NSString *)name;

 

- (CGFloat)height;

 

- (NSInteger)age;

 

 

在.m文件里

//setter

- (void)setName:(NSString *)name

{

    _name = name;

}

 

- (void)setHeight:(CGFloat)height

{

    _height = height;

}

 

- (void)setAge:(NSInteger)age

{

    _age = age;

}

 

//getter

 

- (NSString *)name

{

    return_name;

}

 

- (CGFloat)height

{

    return_height;

}

 

- (NSInteger)age

{

    return_age;

}

 

#pragma mark - override method

//重写description

- (NSString *)description

{

    return  [NSStringstringWithFormat:@"name = %@, age = %ld,height = %.2f",_name,_age,_height];

}

 

#pragma mark - initmethod

 

- (id)initWithname:(NSString *)name age:(NSInteger)age height:(CGFloat)height

{

    self = [superinit];

    if (self != nil) {

        _name = name;

        _age = age;

        _height = height;

    }

    returnself;

}

 

 

我们在main函数内创建几个人类的对象,用一个数组personArr存储

Person *per1 = [[Personalloc] initWithname:@"Frank"age:20height:175];

        Person *per2 = [[Personalloc] initWithname:@"Duke"age:25height:170];

        Person *per3 = [[Personalloc] initWithname:@"Lili"age:22height:165];

        Person *per4 = [[Personalloc] initWithname:@"Mary"age:18height:160];

储对

NSArray *personArr = [[NSArrayalloc] initWithObjects:per1,per2,per3,per4, nil];

 

若想为人分别按照年龄,身高升序排序,按照姓名降序排序,则需要添加方法,如下:

 

//添加比较的方法 compare

//按年龄升序排序

-  (NSComparisonResult)personAge:(Person *)anotherPerson;

-   

//按身高升序排序

-  (NSComparisonResult)personHeight:(Person *)anotherPerson;

 

//按姓名降序排序

- (NSComparisonResult)personNameDescending:(Person *)anotherPerson;

 

 

.m文件对方法实现:

//按年龄升序排序

 

- (NSComparisonResult)personAge:(Person *)anotherPerson

{

    if ([selfage] > [anotherPerson age]) {

        returnNSOrderedDescending; //1

    } elseif ([selfage] == [anotherPerson age])

    {

        returnNSOrderedSame; //0

    } else {

        returnNSOrderedAscending; //-1

    }

}

//按身高升序排序

 

- (NSComparisonResult)personHeight:(Person *)anotherPerson

{

    if ([selfheight] > [anotherPerson height]) {

        returnNSOrderedDescending; //1

    } elseif ([selfheight] == [anotherPerson height])

    {

        returnNSOrderedSame; //0

    } else {

        returnNSOrderedAscending; //-1

    }

 

}

 

//按姓名降序排序

- (NSComparisonResult)personNameDescending:(Person *)anotherPerson

{

        return -[[selfname] compare:[anotherPerson name]];

}

 

在main函数中调用

 

        //对数组元素按年龄升序排序

        NSArray *sortAge = [personArr sortedArrayUsingSelector:@selector(personAge:)];

        NSLog(@"%@",sortAge);

 

       

       

        //对数组元素按身高升序排序

        NSArray *sortHeight = [personArrsortedArrayUsingSelector:@selector(personHeight:)];

        NSLog(@"%@",sortHeight);

 

       

       

        //对数组元素按姓名序排序

        NSArray *sortNameDe = [personArrsortedArrayUsingSelector:@selector(personNameDescending:)];

        NSLog(@"%@",sortNameDe);

 

       

三,对数组的元素降序排序和升序排序

 

NSArray *arr = [[NSArrayalloc] initWithObjects:@"ff",@"bb",@"aa",@"dd", nil];

 

对数组元素升序排序

 

        NSArray *sortArrAscending = [arrsortedArrayUsingSelector:@selector(compare:)];

        NSLog(@"%@",sortArrAscending);

 

//对数组元素降序排序

        //通过block排序

        NSArray *sortAscending = [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {

            //block匿名函数实现比较方法

            //1)id类型转为NSString *类型

            NSString *str1 = (NSString *)obj1;

            NSString *str2 = (NSString *)obj2;

            //字符串比较

            return -[str1 compare:str2];

           

        }];

        NSLog(@"%@",sortAscending);

 

综上所述:

(1),sortedArrayUsingSelector:排序适用于升序排序以及自定义的类排序

(2),block(sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2))排序方式适用于当数组中的对象类型是系统类型(即系统提供的OC类型),并且要降序排序时

 

系统提供的排序方法sortedArrayUsingSelector:还是利用冒泡排序法,只是把 if 里的(compare)判断条件中的要比较的对象空出来了,大于零的条件(return 1)已经给定,也就是按照升序排序,如果前者大于后者,则交换位置

 

系统提供的排序方法sortedArrayUsingComparator:^NSComparisonResult(idobj1, id obj2)也是利用冒泡排序法,它跟sortedArrayUsingSelector:不同,他把if 里的判断条件中的要比较的对象类型让我们自己选择,既可以是任何对象类型, obj1obj2就是让我们自己选择的,大于零的条件已经给定,但是 > 0的返回值也让我们自己选择,也就是按照升序或者降序排序有我们自己决定,如果降序排序,则返回值为-1,若为升序返回值为1;