《Programming with Objective-C》第八章 Working with Blocks

來源:互聯網
上載者:User

標籤:

Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDictionary.

 

Block文法——無參數版本定義(Block的值)
^{    NSLog(@"This is a block");}

 

聲明
void (^simpleBlock)(void);

類似int i;

 

賦值
simpleBlock = ^{    NSLog(@"This is a block");    }

類似i = 2;

 

聲明的時候定義
void (^simpleBlock)(void) = ^{    NSLog(@"This is a block");}

類似int i = 2;

 

調用
simpleBlock();

 

Block文法——帶參數版本定義
^(double firstValue, double secondValue){    return firstValue * secondValue;}

or

^double (double firstValue, double secondValue) {    return firstValue * secondValue;}

 

聲明
double (^multiplyTwoValues)(double, double);

 

賦值
multiplyTwoValues = ^(double firstValue, double secondValue) {    return firstValue * secondValue;};

 

聲明的時候定義
double (^multiplyTwoValues)(double, double) =^(double firstValue, double secondValue) {    return firstValue * secondValue;};

 

調用
double result = multiplyTwoValues(2,3);

 

__block修飾符
int anInteger = 42;void (^testBlock)(void) = ^{    //此時只是Block定義,並沒有執行裡面的函數    NSLog(@"Integer is: %i", anInteger);};anInteger = 84;testBlock();    //Block調用 輸出42

 

Value is captured when the block is defined.

Block定義的時候,將值複製一份給自己,所以該值已經不受外界影響。

 

__block int anInteger = 42;void (^testBlock)(void) = ^{    //此時只是Block定義,並沒有執行裡面的函數    NSLog(@"Integer is: %i", anInteger);    };anInteger = 84;testBlock();    //Block調用 輸出84

 

Because anInteger is declared as a __block variable, its storage is shared with the block declaration.

此時Block裡面的值與外面的值共用同一份記憶體

 

Block與self的恩怨情仇

It’s important to take care when capturing self because it’s easy to create a strong reference cycle when capturing self.

 

因為變數預設是__strong修飾(詳見這裡),所以要時刻注意在block裡面對self的引用(只要出現了self關鍵字就算引用了,因為block會自動capture)

假如self裡面定義了一個block,那麼self有一個指向block的strong指標(比如該block是self的一個strong成員變數);假如block裡面使用了self,則block也預設拷貝了一個指向self的strong指標,此時形成strong reference cycle.

解決方案:在Block前面建立一個__weak類型的指向self的指標,並在block裡面使用該指標。

例子

__weak typeof(self) weakSelf = self;    //學習下這種寫法哦 typeof(self)self.simpleBlock = ^{    [weakSelf f];};...self.simpleBlock();

但是,假如Block裡面又有一個Block,怎麼辦?最好是強引用weakSelf,此時strongSelf強引用的是weakSelf而不是self,所以不會形成strong reference cycle

__weak typeof(self) weakSelf = self;    //學習下這種寫法哦 typeof(self)self.simpleBlock = ^{    [weakSelf f];    __strong typeof(weakSelf) strongSelf = weakSelf;    self.simpleBlock2 = ^{        [strongSelf f];    };    self.simpleBlock2();};...self.simpleBlock();

圖解

一個函數最好只有一個Block參數,且最好是在最後一個

A Block Should Always Be the Last Argument to a Method.

It’s best practice to use only one block argument to a method.

 

使用typedef定義一個block
typedef int (^Sum)(int, int);Sum mySum = ^(int a, int b){    return a+b;}

or

typedef void (^XYZSimpleBlock)(void);@property (copy) XYZSimpleBlock blockProperty;

 

使用copy修飾block的property
@property (nonatomic, copy) Sum mySum;@property (nonatomic, copy) void (^blockProperty)(void);

非ARC下就必須寫copy,because a block needs to be copied to keep track of its captured state outside of the original scope
在ARC下寫不寫copy都無所謂,so it‘s a best practice to set copy property for block whether it‘s ARC or not.

 

《Programming with Objective-C》第八章 Working with Blocks

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.