你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> ios block初級使用

ios block初級使用

編輯:IOS開發綜合

block和GCD是ios高級程序員面試必問的問題,本篇先介紹下block

第一部分:概述


Block是一個C級別的語法以及運行時的一個特性,和標准C中的函數(函數指針)類似,但是其運行需要編譯器和運行時支持,從ios4.0開始就很好的支持Block,個人感覺使用block最大的便利就是簡化的回調過程,以前使用uiview的動畫,進程要控制動畫結束後進行相應的處理,ios4.0之後,uiview新增了對block的支持,現在只要使用簡單的一個block代碼就可以在寫動畫的代碼部分直接添加動畫結束後的操作,還有就是在使用notification的時候block也是非常有幫助的,反正多用就對了,block大大提高了代碼的效率,

block是一個具有匿名功能的內嵌函數,與函數非常相似,,但是Block比之C函數,其靈活性體現在棧內存、堆內存的引用,我們甚至可以將一個Block作為參數傳給其他的函數或者Block。

實體形式如下:

^(傳入參數列){行為主體}

lock實體開頭是“^”,接著是由小括號所包起來的參數列(比如 int a, int b, int c),行為主體由大括號包起來,專有名字叫做block literal。行為主體可以用return回傳值,類型會被compiler自動辨別。如果沒有參數列要寫成: ^(void)。

第二部分:具體用法


一:block的初級用法

 /*test 1  使用^運算子來宣告一個block變數*/
        int multiplier = 7;
        int (^myblock)(int) = ^(int num){
            return num*multiplier;
        };
        
        printf("%d\n",myblock(5));
        
        /*test 2  在需要使用block的地方直接用內嵌的方式將block的內容寫出來*/
        char * myCharacters[3] = {"TomJohn","George","Charles Condomine"};
        qsort_b(myCharacters, 3, sizeof(char*), ^(const void*l,const void*r)//排序函數,個人感覺sort快速排序很好用
                    {
                        char*left = *(char**)l;
                        char*right= *(char**)r;
                        return strncmp(left, right, 1);
                    }
                );
        printf("%s\n",myCharacters[0]);
        /*test 3  在block內修改變量*/
        __block int multiplier2 = 7;
        int(^myblock2)(int) = ^(int num){
            if (num>5) {
                multiplier2 = 0;
            }else{
                multiplier2 = 3;
            }
            return multiplier2;
        };
        NSLog(@"%d,%d\n",myblock2(8),myblock2(3));

二:定義一個block

可以參考,對照block的實體形式

        /*回傳void,參數也是void的block*/
        void(^blockReturningVoidWithVoidArgument)(void);
        /*回傳整數,兩個參數分別是整數和字元形態的block*/
        int (^blockReturningIntWithIntAndCharArguments)(int,char);
        /*回傳void,含有10個block的陣列,每個block都有一個形態為整數的參數*/
        void(^arrayofTenBlockReturningVoidWinIntArgument[10])(int);

三:block和變量

 /*test 1  區域變數的使用方式*/
        
        // 加上__block 修飾詞變量才能在block中修改操作
        int x = 123;
        void (^printXAndY)(int) = ^(int y){
            printf("%d,%d\n",x,y);
        };
        printXAndY(20);
        
        // 加上__block 修飾詞變量才能在block中操作
        
        /*test 2  各個類型的變數和block之間的互動*/
        
            NSInteger localCounter = 42;
            __block char localCharacter;
            void (^aBlock)(void) = ^(void)
            {
//                ++CounterGlobal;//可以存取
                ++CounterStatic;//可以存取
//                CounterGlobal = localCounter;
                localCharacter = 'a';
            };
            ++localCounter;
            localCharacter = 'b';
            aBlock();
            printf("test2:%ld,%ld,%c\n",localCounter,CounterStatic,localCharacter);
四:使用block

/*test 1  當block宣告成一個變數時,我們可以像使用一般函數的方式來使用它*/
        
        int (^twoFrom)(int) = ^(int anInt){
            return anInt-1;
        };
        printf("1 from 10 is %d\n",twoFrom(10));
        
        
        float (^distanceTraveled)(float,float,float) = ^(float startingSpeed,float acceleration,float time){
            float distance = (startingSpeed*time)+(0.5*acceleration*time*time);
            return distance;
        };
        printf("howFar %f\n",distanceTraveled(0.0,9.8,1.0));
        
        /*test 2  一般情況下若是將block當做是參數傳入函數,我們通常會使用內嵌的方式來使用block*/
        
        char*myCharacter_s[3] = {"TomJohn","George","Charles Condomine"};
        qsort_b(myCharacter_s, 3, sizeof(char*), ^(const void*l,const void*r){
            char*left = *(char**)l;
            char*right = *(char**)r;
            return strncmp(left, right, 1);
            
        });
        
        /*test 3  在上邊的例子中,block本身就是函數參數的一部分,在下一個例子中dispatch——apply函數中使用block,dispatch_apply的定義如下*/
//        void dispatch_apply(size_t iterations,dispatch_queue_t queue,void(^block)(size_t));
        size_t count = 12;
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_apply(count, queue, ^(size_t i){//類似於for循環
            printf("%zu\n",i*2);
        });
        
        
        /*test 4  SDK中提供了很多使用block的方法,我們可以像傳遞一般參數的方式來傳遞block,下面這個范例示范如何在一個陣列的前五筆資料中取出我們想要的資料的索引值*/
        //所有的資料
        NSArray*array = [NSArray arrayWithObjects:@"A",@"B",@"C",@"A",@"B",@"Z",@"G",@"are",@"Q", nil];
        //我們只要這個集合內的資料
        NSSet*filterSet = [NSSet setWithObjects:@"A",@"B",@"Z",@"Q", nil];
        BOOL(^test)(id obj,NSUInteger idx,BOOL*stop);
        test = ^(id obj,NSUInteger idx,BOOL *stop){
            if (idx<5) {
                if ([filterSet containsObject:obj]) {
                    return YES;
                }
            }
            return NO;
        };
        NSIndexSet*indexes = [array indexesOfObjectsPassingTest:test];
        NSLog(@"indexes:%@",indexes);

如果雷同純屬巧合

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved