天天看點

block的定義和使用,以及block與數組排序

//
//  main.m
//  89_oc_classexam
//
//  Created by Quan.Zh. on 14-8-9.
//  Copyright (c) 2014年 藍鷗科技. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Student.h"
// 聲明一個求和的函數
int sum(int a, int b);
int sum(int a, int b)
{
    int sum;
    sum = a + b;
    return sum;
}
// 給函數類型起别名
typedef int (*SUM) (int, int);

// 給block起别名
typedef int (^MyBlock) (int, int);





int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
#pragma mark block的定義、使用、block與變量的關系

        // 寫一個函數指針指向sum函數
        // 指針的類型:int (*) (inr,int)
        // 變量名:p
        // 值:sum
        int (*p) (int, int) = sum;
        sum (19,20);
        p (12,33);
        
        
        
        
// 聲明一個block變量
        // 類型:int (^) (int,int)
        // 變量名:myBlock
        int (^myBlock) (int, int);
        // block的值
        myBlock = ^(int a, int b) { // ^标志着後邊内容是一個block類型的
            return a+b;
        };
        // 傳回值是int,
        // 參數是int,int
        
        
        
        // 定義三個block,實作:求差、商、積
        int (^dilBlock) (int, int);
        dilBlock = ^(int a, int b) {
            return a - b;
        };
        // block的簡化寫法1
        int (^shangBlock) (int, int) = ^(int a, int b) {
            return a / b;
        };

        // block的簡便寫法2:typedef
        
        int (^jiBlock) (int, int);
        jiBlock = ^(int a, int b) {
            return a * b;
        };
        
        // 使用别名定義一個block
        MyBlock moBlock = ^(int a, int b) {
            return a % b;
        };
        
        
// block的使用和函數指針一樣,在變量名後直接傳遞參數值
        int a = 10, b = 20;
        NSLog(@"積 = %d", jiBlock(a, b));
        NSLog(@"差 = %d", dilBlock(a, b));
        NSLog(@"商 = %d", shangBlock(a,b));
        NSLog(@"和 = %d", myBlock(a,b));
        NSLog(@"摸 = %d", moBlock(a, b));
        
        
        
#pragma mark block與局部變量和全局變量的關系
// block對局部變量的修改值操作,需要在局部變量前添加__block修飾
// block對全局變量的修改,可以直接修改值
        // block内部公用的變量可以在block之外統一定義,如:
        int beishu = 10;    //  定義一個局部變量
        
        MyBlock myBlock1 = ^(int a, int b) {
            return (a + b) *beishu;
        };
        
        
        
        //  block内部可以調用局部變量,但是在block内部更改局部變量的值時,局部變量需要用__block修飾
        __block int beishu1 = 10;   //  定義一個__block修飾的局部變量
        
        MyBlock myBlock2 = ^(int a, int b) {
            beishu1 = 100;  // 經過修飾的beishu1可以修改
//            beishu = 100;   // 未經__block修飾的beishu不可以修改值
            
            return (a + b) * beishu1;
        };
        
        


        
#pragma mark block與數組排序

        NSArray *array = @[@"123", @"23", @"54", @"345"];
    
        NSComparisonResult (^sortArray) (id, id) = ^(id obj1, id obj2){
            // 根據數值大小進行排序,首先要将字元串轉化為整型類型
            int i1 = [obj1 intValue];
            int i2 = [obj2 intValue];
            // 比較并傳回兩個值的大小
            if (i1 > i2) {
                return NSOrderedAscending;
            } else if (i1 < i2) {
                return NSOrderedDescending;
            }
                return NSOrderedSame;
            
        };
       // 把剛剛寫的block作為參數,傳遞給sortedArrayUsingComparator:方法,讓數組根據我們寫的block進行排序
        array = [array sortedArrayUsingComparator:sortArray];
        // 列印結果
        NSLog(@"%@",array);
        }
    

        
        
        
        
#pragma mark 給學生按照姓名和年齡排序(使用block)
        
       // 初始化并建立一個學生對象
        Student *stu1 = [[Student alloc] initWithNmae:@"Z三" age:24];
        Student *stu2 = [[Student alloc] initWithNmae:@"L斯" age:23];
        Student *stu3 = [[Student alloc] initWithNmae:@"W五" age:12];
        Student *stu4 = [[Student alloc] initWithNmae:@"ZH劉" age:44];
        // 将學生裝進數組中
        NSArray *stuArray = [NSArray arrayWithObjects:stu1,stu2,stu3,stu4,nil];
        // 定義一個排序的block
        // 根據姓名排序
        NSComparisonResult (^paixuByName) (id, id);
        paixuByName = ^(id obj1, id obj2) {
            if ([[obj1 getName] compare:[obj2 getName]] > 0) {
                return NSOrderedAscending;
            } else if ([[obj1 getName] compare:[obj2 getName]] < 0) {
                return NSOrderedDescending;
            } else
                return NSOrderedSame;
        };
        
        // 将上邊定義的stuArray數組放在以下方法中,同時引用paixuByName,根據我們寫的方法進行排序
        stuArray = [stuArray sortedArrayUsingComparator:paixuByName];
        for (int i = 0; i < stuArray.count; i++) {
             NSLog(@"%@",stuArray[i]);
        }
        
        // 根據年齡從小到大的排序
        NSLog(@"按照年齡升序排序");
        NSComparisonResult (^paixuByAge) (id, id);
        
        paixuByAge = ^(id obj1, id obj2) {
            if ([obj1 getAge] > [obj2 getAge]) {
                return NSOrderedDescending;
            } else if ([obj1 getAge] < [obj2 getAge]) {
                return NSOrderedAscending;
            }
            return NSOrderedSame;
        };
        
        stuArray = [stuArray sortedArrayUsingComparator:paixuByAge];
        for (int i = 0; i < stuArray.count; i++) {
            NSLog(@"%@",stuArray[i]);
            }
        
//************************************************************************************************//
        // 使用block排序的常用簡便寫法(block其實就是一個參數):選中參數按回車,系統自動生成block的實作頭;
        stuArray = [stuArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
            if ([obj1 getAge] > [obj2 getAge]) {    // 排序代碼
                return NSOrderedDescending;
            } else if ([obj1 getAge] < [obj2 getAge]) {
                return NSOrderedAscending;
            }
            return NSOrderedSame;

        }];
        for (int i = 0; i < stuArray.count; i++) {
            NSLog(@"@@@@@@@@@@@@@%@",stuArray[i]);
        }

//***********************************************************************************************//
        
        }
    return 0;

    }