6、Block,数组排序

Block语法

Block:块语法,本质上是匿名函数(没有名称的函数)
标准C⾥⾯没有Block,C语⾔的后期扩展版本,加⼊了匿名函数。
C++、JS、Swift等语⾔,有类似语法,叫做闭包。
Block语法和函数指针很相似

函数

C语⾔中,实现某⼀功能的代码段。
完整的函数包含两部分:函数声明、函数定义
函数声明,即函数原型。例如:int sum(int x,int y);具有两个整型参数,⼀个整型返回值的函数。
函数定义,即函数实现。例如:

int sum(int x,int y){
 retrun x + y;
}

函数指针

函数指针(变量):存放函数地址(函数名)的指针变量。

int (*p)(int x,int y) = sum; 

函数指针类型:int (*)(int x,int y) 即:指向 两个整型参数,⼀个整型返回值 函数 的指针。
函数指针变量:p
函数指针的值:sum

Block

匿名函数:没有名称的函数。
例如 :

int (int x, int y) 

没有名称的函数应该如何调⽤?(有名称的话,可以直接调⽤,也可以通过函数指针来调⽤)

因为Block是匿名函数,block变量存放的函数的实现,通过block变量能直接调⽤函数

Block语法

Block类型:int (^)(int)
Block变量:myBlock
Block值:^ int (int num){ return 7 * num;}
即:^ 返回值类型 (参数列表){函数体} 其中 返回值类型可以省略。


Block使⽤

int (^block1)(int x,int y) = ^(int x,int y){
    return x + y;
}; 
int a = block1(32 , 34);//block的使⽤和函数指针的使⽤类似。
NSLog(@“%d”,a); 

typedef

typedef int (^BlockType)(int x,int y)
原类型:int (^)(int x,int y)
新类型:BlockType

//Block块的typedef
typedef int (^myBlock)(int,int);
myBlock mb = ^(int a,int b){
    return a+b;
};
NSLog(@"%d",mb(3,6));

Block块参数省略时,里面可以写多个任意类型的参数,但返回值类型必须是int

typedef int (^myBlock)();
myBlock mb3 = ^(int a,int b,int c){
    return a+b+c;
};
NSLog(@"%d",mb3(3,6,9));

description方法/NSLog函数

description方法/NSLog函数

1.description方法是NSObject自带的方法,包括类方法和对象方法

+ (NSString *)description; // 默认返回类名
- (NSString *)description; // 默认返回<类名:内存地址>

2.默认情况下利用NSLog和%@输出对象的时返回的就是类名和内存地址
3.修改NSLog和%@的默认输出:重写类对象或者实例对象的description方法即可。
因为NSLog函数进行打印的时候会自动调用description方法

/********** Person.h文件***********/
#import <Foundation/Foundation.h>
@interface Person : NSObject
+ (NSString *)description;
- (NSString *)description;
@property int age;
@property NSString *name;
@end
/*********** Person.m文件***********/
#import "Person.h"
@implementation Person
#pragma mark 类对象输出的结果
+ (NSString *)description{
    return @"AAA";
}
#pragma mark 实例对象输出的结果
- (NSString *)description{
    // NSLog(@"%@",self); 引发死循环
    return [NSString stringWithFormat:@"name = %@ age = %d",_name,_age];}
@end
/**************main.m文件***********/
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]){
    Class c = [Person class];
    NSLog(@"%@",c);
    Person *person = [[Person alloc] init];
    person.name = @"John";
    person.age = 20;        //执行NSLog函数的时候会调用description方法默认返回<类名/对象名: 地址> 
    NSLog(@"%@",person);
}
/*********** 丰富日志输出 ***********/
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]){
    //打印person对象地址
    Person *person = [[Person alloc] init];        
    NSLog(@"%@",person); // <Person: 0x100200ae0>  
    // 打印person指针的地址
    NSLog(@"%p",person); // 0x100200ae0 对象和指针地址一致        
    // 指针变量的地址
    NSLog(@"%p",&person);// 0x7fff5fbff8e8        
    // NSLog用%s无法输出带有中文的文件路径,可以用c语言中的printf和%s来代替  
    // NSLog(@"%s",__FILE__);
    printf("%s",__FILE__);        //输出当前方法
    NSLog(@"%s",__FUNCTION__);  // 返回 main 
}

Block实现数组排序

main.h

/*
     0、按年龄升序排列
     1、按学号升序排列
     2、按学号降序排列
     3、按姓名升序排列
     4、按姓名降序排列
     */
    Student *stu1 = [Student studentWithName:@"ZhangSan" age:18 num:2];
    Student *stu2 = [Student studentWithName:@"LiSi" age:20 num:1];
    Student *stu3 = [Student studentWithName:@"WangWu" age:10 num:3];

    NSMutableArray *arr = [NSMutableArray arrayWithObjects:stu1,stu2,stu3, nil];
    //因为重写了description方法,能够输出对象数组的详细信息,而不是只输出一个首地址
    NSLog(@"%@",arr);
    //通过遍历实现打印对象数组
    for (Student *stu in arr) {
        [stu introduce];
    }
     //0、按年龄升序排列
    NSLog(@"--------年龄升序----------");
    //此方法不好,代码量过大,其实可以直接return [stu1 age] > [stu2 age],因为有NSComparisonResult的存在会自动把返回值变成NSComparisonResult类型的
    [arr sortUsingComparator:^NSComparisonResult(id obj1,id obj2){
     //数组排序方法:sortUsingComparator,里面应该是封装了双层for循环,参数是一个返回值为NSComparisonResult类型的Block块
        Student *stu1 = (Student *)obj1;//此处用于说明接收的是Student类类型的参数
        Student *stu2 = (Student *)obj2;
        if([stu1 age] > [stu2 age]){
            return NSOrderedDescending;//降序
        }
        else if([stu1 age] < [stu2 age]){
            return NSOrderedAscending;//升序
        }
        else {
            return NSOrderedSame;//相等
        }
    }];
    NSLog(@"%@",arr);

    //1、按学号升序排列
    NSLog(@"--------学号升序----------");
    //用NSComparator类型的sort1接收NSComparisonResult类型的结果
    //因为:typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
    NSComparator sort1 = ^(id obj1,id obj2){
        Student *stu1 = (Student *)obj1;
        Student *stu2 = (Student *)obj2;
        if ([stu1 num] > [stu2 num]) {
            return NSOrderedDescending;
        }
        else if([stu1 num] < [stu2 num]){
            return NSOrderedAscending;
        }
        else{
            return NSOrderedSame;
        }
    };
    [arr sortUsingComparator:sort1];
    for (Student *stu in arr) {
        [stu introduce];
    }

    //2、按学号降序排列
    NSLog(@"--------学号降序----------");
    /*
    NSComparator sort2 = ^(id obj1,id obj2){
        Student *stu1 = (Student *)obj1;
        Student *stu2 = (Student *)obj2;
        if ([stu1 num] > [stu2 num]) {
            return NSOrderedDescending;
        }
        else if([stu1 num] < [stu2 num]){
            return NSOrderedAscending;
        }
        else{
            return NSOrderedSame;
        }
    };
    */
    NSComparator sort2 = ^NSComparisonResult(Student *stu1,Student *stu2){
        return [stu1 num] < [stu2 num];//与升序相比只需要把 > 换成 < 就行了
    };

    [arr sortUsingComparator:sort2];
    for (Student *stu in arr) {
        [stu introduce];
    }

    //3、按姓名升序排列
    NSLog(@"--------姓名升序----------");
    /*
    NSComparator sort3 = ^(id obj1,id obj2){
        Student *stu1 = (Student *)obj1;
        Student *stu2 = (Student *)obj2;
        return [[stu1 name] compare: [stu2 name]];
    };
     */
    //此处直接用Student作为参数,则内部不需要再写Student *stu1 = (Student *)obj1;用来接收
    NSComparator sort3 = ^(Student * stu1,Student * obj2){
        return [[stu1 name] compare: [stu2 name]];//字符串类型比较要用compare:方法,返回值直接是NSComparisonResult类型的
    };
    [arr sortUsingComparator:sort3];
    for (Student *stu in arr) {
        [stu introduce];
    }

    //4、按姓名降序排列
    NSLog(@"--------姓名降序----------");
    NSComparator sort4 = ^(id obj1,id obj2){
        Student *stu1 = (Student *)obj1;
        Student *stu2 = (Student *)obj2;

        return -[[stu1 name] compare: [stu2 name]];

    };
    [arr sortUsingComparator:sort4];
    NSLog(@"%@",[arr description]);//重写了系统自带的description方法,可以直接输出数组的值,而不是只有每个对象的首地址
    /*
    for (Student *stu in arr) {
        [stu introduce];
    }
    */

Student.h

@interface Student : NSObject
{
    NSString * _name;
    NSInteger _age;
    NSInteger _num;
}
@property(nonatomic,retain)NSString * name;
@property(nonatomic,assign)NSInteger age;
@property(nonatomic,assign)NSInteger num;
-(instancetype)initWithName:(NSString *)name
                        age:(NSInteger)age
                        num:(NSInteger)num;
+(instancetype)studentWithName:(NSString *)name
                           age:(NSInteger)age
                           num:(NSInteger)num;
//自我介绍
-(void)introduce;
//系统自带方法,重写时就不需要声明了
//-(NSString *)description;
@end

Student.m

@implementation Student
-(instancetype)initWithName:(NSString *)name
                        age:(NSInteger)age
                        num:(NSInteger)num{
    self = [super init];
    if (self) {
        _name = name;
        _age = age;
        _num = num;
    }
    return self;
}
+(instancetype)studentWithName:(NSString *)name
                           age:(NSInteger)age
                           num:(NSInteger)num{
    Student *stu = [[Student alloc]initWithName:name age:age num:num];
    return stu;
}
-(void)introduce{
    NSLog(@"My name is %@,%ld years old,StudyNum is %ld",_name,_age,_num);
}
//重写description方法
-(NSString *)description{
    return [NSString stringWithFormat:@"name:%@,age:%ld,num:%ld",_name,_age,_num];
}
@end

字面量:语法糖

Literals (字⾯量),是⼀种简易表⽰值的⽅法

未使用字面量 使用字面量
NSString *str1 = [NSString stringWithFormat:@”234”]; NSString *str2 = @”234”;
NSArray *array = [NSArray arrayWithObject:a,b,c,nil]; NSArray *array = @[a,b,c];
[array objectAtIndex:1] array[1]
NSDictionary *dict = dictionnaryWithObjectAndKeys:@”laowang”,@”name”,@”man”,@”sex”,nil; NSDictionary *dict = @{@”name”:@”laowang”,@”sex”:@”man”};
[dict valueForKey:k] dict[k]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章