Objective C中Blocks塊的介紹

2021-07-26 18:19:41 字數 3278 閱讀 1323

*注:解釋內容主要參考《objective-c 高階程式設計》

1.介紹:

blocks是c語言的擴充功能:帶有自動變數(區域性變數)的匿名函式。

blocks的語法:^

返回值型別

引數列表

表示式

例如:

^int (int c)
其中,

返回值型別 是可以省略的,會按return型別返回,如果不需要引數,那麼

引數列表 也可以省略,如:

^

2.block型別變數

int (^blk)(int) = ^(int c);

int x = blk(5);

nslog(@"x = %d",x);

block值

^(int

c) 被賦值給了變數blk中,blk即為block變數。

利用typedef定義block別名:

typedef int (^blk_1)(int);

blk_1 blkk = ^(int x);

nslog(@"x = %d",blkk(3));

意指用blk_1來代替int ^(int);這種塊,之後呼叫賦值什麼的會更舒服。

3.截獲自動變數值

int x = 1;

void (^blk)(void) = ^;

x = 6;

blk();

以上**輸出結果 zhi = 1;可見在block截獲的是自動變數x的值,之後改變x,並不會對塊的執行結果有影響。並且我們如果想在塊中改變x的值是無法通過編譯的。如果我們想在塊中改變x的值,需要用__block說明符

4.__block說明符

__block int x = 1;

void (^blk)(void) = ^;

blk();

nslog(@"x = %d",x);

輸出結果為 x = 6

用__block修飾x後,便可以在塊中改變擷取的自動變數x,那麼:

__block int x = 1;

void (^blk)(void) = ^;

x = 7;

blk();

輸出結果為 x = 7

這裡思考,如果我們不用__block,擷取oc物件,會怎麼樣:

nsstring *age = @"26";

nsmutabledictionary *dic =[[nsmutabledictionary alloc]init];

[dic setobject:age forkey:@"age"];

void (^blk)(void) = ^;

nsstring *age2 = [dic objectforkey:@"age"];

age2 = @"18";

[dic removeobjectforkey:@"age"];

[dic setobject:age2 forkey:@"age"];

blk();

輸出結果為 age = 18

這裡我們初始化了乙個dic,裡面有乙個key為@"age"的nsstring,初始值為26,在塊中輸出字典中字串的值,然後在塊執行前,改變dic中字串。

由此我們聯想:

nsstring *age = @"26";

nsmutabledictionary *dic =[[nsmutabledictionary alloc]init];

[dic setobject:age forkey:@"age"];

void (^blk)(void) = ^;

blk();

nsstring *a = [dic objectforkey:@"age"];

nslog(@"age = %@",a);

輸出 age = 18

所以在塊中也能改變dic的值。

這裡我們分析,我們用塊擷取的是nsmutabledicitionary的例項指標,不能對其賦值,但是可以使用它,即可以向其中新增改變物件。

*這裡我們要注意:

const char text = "helloworld";

const char *text1 = "helloworld";

void (^blk)(void) = ^;

blk();

我們可以使用擷取*text1,但是text不可以,因為擷取自動變數的方法並沒有實現對c語言陣列的接獲,應該用指標方法解決。

4.blocks的實現

我們利用clang的指令轉變一下我們的檔案,開啟終端,利用 clang -rewrite-objc 『檔名』 對我們的檔案進行操作,我們的檔案內容如下:

int main();

int jieguo = blk();

return 0;

}

宣告乙個簡單的塊,截獲了自動變數 int i,我們用clang指令操作它得到.cpp檔案:

struct __main_block_impl_0 

};//塊中函式

static int __main_block_func_0(struct __main_block_impl_0 *__cself)

由於轉化後**太多,就只擷取了一部分。可以看到結構體建構函式初始化 i(_i) , 讓i = _i,這是乙個copy的過程,所以外部改變自動變數的值,不會影響到塊中的值。

如果使用__block修飾的話:

struct __block_byref_i_0 ;

struct __main_block_impl_0

};static int __main_block_func_0(struct __main_block_impl_0 *__cself, int x)

可以看到,在建構函式中,i(_i->__forwarding) , 這裡用乙個結構體__block_byref_i_0,以指標的方式去儲存自動變數,儲存了變數的位址,那麼後續改變自動變數,塊中的值也會相應改變。

有關塊迴圈引用的問題,及各種使用會在後面文章中介紹。

objc msgSend呼叫引數是block的函式

有乙個函式的引數是block 例 void delete nsstring value result callbackblcok callback 正常的呼叫就是如下 x sharedinstance delete value result int number 複製 突然想到如果都用runtime...

objective c中命名規範

一 關於objective c中類的命名規範 1 類名 及其 category name 和 protocal name 的首字母大寫,寫使用首字母大寫的形式 分割單詞。駝峰標示 2 在面向特定應用的 中,類名應盡量避免使用字首,每個類都使用相同的字首影響可讀性。3 在面向多應用的 中,推薦使用字首...

Objective C中的快取

nscache可以設定數量限制,通過countlimit與 totalcostlimit來限制cache的數量或者限制cost。當快取的數量超過countlimit,或者cost之和超過totalcostlimit,nscache會自動釋放部分快取。例子如下 可以看到,cache中只保留了最新的30...