關(guān)于我的倉庫
- 這篇文章是我為面試準備的iOS基礎(chǔ)知識學習中的一篇
- 我將準備面試中找到的所有學習資料比藻,寫的Demo,寫的博客都放在了這個倉庫里iOS-Engineer-Interview
- 歡迎star????
- 其中的博客在簡書芯急,CSDN都有發(fā)布
- 博客中提到的相關(guān)的代碼Demo可以在倉庫里相應(yīng)的文件夾里找到
前言
- 本文主要是對于《高級編程》類似于總結(jié)的學習筆記
準備工作
- 閱讀《Objective-C 高級編程》中的p.79 ~ 91
Blocks概要
- 一句話概括Blocks的擴充功能:帶有自動變量(局部變量)的匿名函數(shù)
疑惑: p.81 buttonId
int buttonID = 0;
void buttonCallback(int event) {
NSLog(@"button:%d event = %d", buttonID, event);
}
void setButtonCallback(int offset, void (*p)(int)) {
p(offset);
}
void setButtonCallbacks() {
for (int i = 0; i < 10; i++) {
buttonID = i;
setButtonCallback(0 + i, &buttonCallback);
}
}
- 書上沒有給出setButtonCallback函數(shù)的具體實現(xiàn)鹊漠,但估計肯定是這樣的,因為我們使用函數(shù)指針很大一部分就是為了使用函數(shù)回調(diào)
- 可是書上說慰技,這樣寫了會出現(xiàn)問題腾誉,我覺得他的意思是說這樣寫會出現(xiàn)buttonID只會是for循環(huán)的最后一個徘层,也就是9
- 可是我實驗下來和正常情況沒有什么區(qū)別,不是很懂
887D7308-7318-4B92-A638-EBFF549147A1
Block語法
與一般C語言函數(shù)不同點:
- 沒有函數(shù)名
- 帶有“^”號【插入記號】
格式
標準格式
ECDEC5C7-C6FF-4F5F-A1B8-DB8BA7F2BB6C
^int (int count){return count + 1;}
省略格式
- 可以省略返回值類型
- 省略返回值類型的情況下利职,return什么類型返回值就是什么類型趣效,不寫return的話默認就是void
- 可以省略參數(shù)列表
- 沒有參數(shù)的情況下block可以這么寫
60F591B8-D410-4FE9-886F-CFC273B52AEB
- 也可以直接把(void)省略,直接這么寫
B89A2A1D-FFEB-49F7-867B-721ABAB15A98
- 所以我們的block省略完可以這么寫:
40B1C054-38B8-42A4-AD0A-43608AB50B85
block變量
- block變量類似于函數(shù)指針【聯(lián)想:我們說block是匿名函數(shù)】
- 對于函數(shù)猪贪,我們可以使用一個函數(shù)指針跷敬,將函數(shù)的地址賦值給函數(shù)指針,在調(diào)用函數(shù)的時候可以直接通過函數(shù)指針調(diào)用函數(shù)
//ex:C語言函數(shù)指針
int func(int count) {
return count + 1;
}
int (*funcptr)(int) = &func;
//這樣子下面兩個語句代表的含義一樣
int res = func(2);
int res = funcptr(2);
- 同樣對于block热押,我們可以使用block變量調(diào)用block中的表達式
- 聲明block變量的語法和函數(shù)指針基本一致西傀,只是把*號換成了^號
2E876C3B-C47B-4345-A03C-5794F45A8996
- block變量和C語言變量完全相同,可以作為以下用途:
- 自動變量
- 函數(shù)參數(shù)
- 靜態(tài)變量
- 靜態(tài)全局變量
- 全局變量
截獲自動變量
- 看一段代碼:
int dmy = 256;
int val = 10;
const char *fmt = "val = %d\n";
void (^blk)(void) = ^{
printf(fmt, val);
};
val = 2;
fmt = "THESE VALUES WERE CHANGED. val = %d\n";
blk();
- 結(jié)果為val = 10桶癣,而不是2池凄,也就是說val這個變量被截獲了,截獲時它是10鬼廓,雖然在塊里面的代碼在val = 2之后才被執(zhí)行,但打印的依然是截獲時的10致盟,這就是截獲自動變量
- 也就是說變量在代碼運行到定義那一塊就被截獲了碎税,執(zhí)行的時候已經(jīng)不是原變量了
__block說明符
- block可以截獲變量,但是不能在塊里修改變量的值
668D72AD-79AB-47D5-842E-C3CDFCFF8374
- 此時就是需要使用__block修飾符修飾變量馏锡,對需要在block內(nèi)進行賦值的變量雷蹂,使用修飾符修飾,保證可以對變量進行賦值
- 賦值后按序執(zhí)行杯道,也就是說執(zhí)行完了以后匪煌,變量的值就是塊里面的新的值
EBAFF0CC-6012-43D7-9B20-02DBA469A3DD
- 比如上述代碼,就過就是1而不是0党巾,還是要記住萎庭,block的定義和執(zhí)行是分為兩塊的,兩者可能會垮文件齿拂,相隔十萬八千里
- 但只有執(zhí)行完了代碼才會生效
截獲的自動變量
- 這一段主要講的東西我認為其實就是我們捕獲到的東西不能賦值驳规,但是如果只是拿來用的話是沒問題的