*注:解釋內容主要參考《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...