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]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章