• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            CG@CPPBLOG

            /*=========================================*/
            隨筆 - 76, 文章 - 39, 評論 - 137, 引用 - 0
            數(shù)據(jù)加載中……

            用OBJC編程 7 - Working with Blocks

            用OBJC編程 7 - Working with Blocks

            Block 是語言級別的特性。它是一個(gè)OBJC的對象,可以被加入容器如NSArray或NSDictionary。它可以捕獲所處作用域的數(shù)值,非常類似其它語言的closure或者lambda。

            語法
            ^{
                NSLog(@"This is a block");
            }

            可以像函數(shù)指針那樣聲明一個(gè)變量來持有這個(gè)block
            void (^simpleBlock)(void);
            simpleBlock = ^{
               NSLog(@"This is a block");
            }; // 注意這里有一個(gè)分號

            也可以這樣寫
            void (^simpleBlock)(void= ^{
                NSLog(@"This is a block");
            };

            調(diào)用這個(gè)block
            simpleBlock();

            帶上參數(shù)和返回值
            ^double (double firstValue, double secondValue){
                
            return firstValue*secondValue;
            }
            // ,,,,,,,,,,,
            double (^multiplyTwoValues)(doubledouble= 
                
            ^(double firstValue, double secondValue) { // 返回值類型可以省略
                      return firstValue*secondValue;
                 };

            double result = multiplyTwoValues(2,4);
            NSLog(@"The result is %f", result);

            捕獲Enclosing Scope內(nèi)的值,一旦捕獲,這個(gè)值就不會變化,即便后續(xù)改變這個(gè)值
            -(void)testMethod{
              
            int anInteger = 42;
              
            void (^testBlock)(void= ^{
                   NSLog(@"Integer is: %i", anInteger);
              }
              anInteger = 84;
              testBlock(); // 仍然輸出42
            }

            使用__block
            __block int anInteger = 42;
            void (^testBlock)(void= ^{
              NSLog(@"Integer is: %i", anInteger);
            };
            anInteger = 84:
            testBlock();  // output 84;

            // ,,,,,,,,,,,,,

            _block int anInteger = 42;
            void (^testBlock)(void= ^{
              NSLog(@"Integer is: %i", anInteger); // output 42
              anInteger = 100;
            };

            testBlock();
            NSLog(@"Value of original variable is now: %i", anInteger); // output 100;

            通過參數(shù)傳遞Block,例如實(shí)現(xiàn)一個(gè)回調(diào)
            -(IBAction)fetchRemoveInformation:(id)sender{
              [self showProgressIndicator];
              XYZWebTask *task = //,,,

              [task beginTaskWithCallbackBlock:^{
                    [self hideProgressIndicator];
                  }];
            }

            // beginTaskWithCallbackBlock 的定義是這樣的

            -(void)beginTaskWithCallbackBlock:(void)(^)(void))callbackBlock{
              
            //,,,
              callbackBlock();
            }

            最佳實(shí)踐是將block作為最后一個(gè)參數(shù),這樣便于閱讀。

            也可以使用typedef簡化語法
            typedef void (^XYZSimpleBlock)(void);
            //,,,,,,,,,,,,,,,
            XYZSimpleBlock anotherBlock = ^/*,,,*/ };
            //,,,,,,,,,,,,
            -(void)beginFetchWithCallbackBlock:(XYZSimpleBlock)callbackBlock{
                
            //,,,,
                callbackBlock();
            }

            可以將block作為屬性
            @interface XYZObject : NSObject
            @property (copy) void (^blockProperty)(void); // 必須使用copy
            @end
            //,,,,,,,,,,,,,,
            self.blockProperty = ^/* ,,, */ };
            self.blockProperty();

            避免強(qiáng)引用循環(huán)
            在block里捕獲self,諸如在一個(gè)callback block里,會引入內(nèi)存管理問題。block會會維護(hù)一個(gè)捕獲對象的強(qiáng)引用,包括self
            @interface XYZBlockKeeper : NSObject
            @property (copy) void (^block)(void);
            @end
            ////////////////////////
            @implementation XYZBlockKeeper
            -(void)configureBlock{
              self.block = ^{
                [self doSomething];    // 捕獲了一個(gè)self的強(qiáng)引用
                                       
            // 建立了一個(gè)強(qiáng)引用循環(huán)
              }
            }
            @end

            上述代碼會產(chǎn)生一個(gè)編譯警告,為了避免這種情況,最佳實(shí)踐是捕獲一個(gè)self的弱引用
            -(void)configureBlock{
               XYZBlockKeeper * __weak weakSelf = self;
               self.block = ^ {
                  [weakSelf doSomething];
               };
            }

            block可以簡化枚舉(略)
            block可以簡化并發(fā)任務(wù)(略)



            posted on 2013-11-21 19:20 cuigang 閱讀(329) 評論(0)  編輯 收藏 引用 所屬分類: OBJC

            大香网伊人久久综合网2020| 久久免费国产精品一区二区| 99久久精品国产麻豆| 亚洲综合久久夜AV | 9999国产精品欧美久久久久久| 东方aⅴ免费观看久久av| 狠狠精品干练久久久无码中文字幕| 亚洲AV日韩AV天堂久久| 伊人久久大香线蕉综合热线| 青草影院天堂男人久久| 国产一级持黄大片99久久| 男女久久久国产一区二区三区| 狠狠色狠狠色综合久久| 一本一道久久a久久精品综合 | 国产精品亚洲美女久久久| 国产一区二区三区久久精品| 久久久久99精品成人片直播| 日产精品久久久一区二区| 蜜臀av性久久久久蜜臀aⅴ麻豆| 久久久久久久波多野结衣高潮 | 亚洲乱亚洲乱淫久久| 青青草国产成人久久91网| 99久久精品免费观看国产| 久久er国产精品免费观看2| 久久se精品一区二区| 日本福利片国产午夜久久| 久久99精品免费一区二区| 色综合久久久久综合99| 国产亚洲精品久久久久秋霞| 一本久久知道综合久久| 久久精品人人做人人爽97| 久久夜色tv网站| 久久综合久久鬼色| 97精品国产97久久久久久免费| 日韩人妻无码精品久久久不卡| 国产综合久久久久| 很黄很污的网站久久mimi色| 日本五月天婷久久网站| 国产亚洲欧美成人久久片| 久久久久久极精品久久久| 99久久99久久精品国产片果冻|