亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS中Block的回調使用和解析詳解

2020-07-26 03:12:02
字體:
來源:轉載
供稿:網友

Block 回調實現

先跟著我實現最簡單的 Block 回調傳參的使用,如果你能舉一反三,基本上可以滿足了 OC 中的開發需求。已經實現的同學可以跳到下一節。

首先解釋一下我們例子要實現什么功能(其實是爛大街又最形象的例子):

有兩個視圖控制器 A 和 B,現在點擊 A 上的按鈕跳轉到視圖 B ,并在 B 中的textfield 輸入字符串,點擊 B 中的跳轉按鈕跳轉回 A ,并將之前輸入的字符串

顯示在 A 中的 label 上。也就是說 A 視圖中需要回調 B 視圖中的數據。

想不明白的同學可以看一看最終實現的效果圖:

這里不再對 Block 的語法做說明了。

首先,我們需要定義兩個試圖控制器 AViewController BViewController,現在我們需要思考一下,Block 應該在哪里定義呢?

我們可以簡單地這樣思考,需要回調數據的是 A 視圖,那么 Block 就應該在 B 中定義,用于獲取傳入回調數據。

因此我們在 BViewController.h 中定義如下:

//BViewController.h#import <UIKit/UIKit.h>typedef void(^CallBackBlcok) (NSString *text);//1@interface BViewController : UIViewController@property (nonatomic,copy)CallBackBlcok callBackBlock;//2@end

在這里,代碼 1 用 typedef 定義了 void(^) (NSString *text)的別名為 CallBackBlcok 。這樣我們就可以在代碼 2 中,使用這個別名定義一個 Block 類型的變量 callBackBlock。

在定義了 callBackBlock 之后,我們可以在 B 中的點擊事件中添加 callBackBlock 的傳參操作:

//BViewController.m- (IBAction)click:(id)sender { self.callBackBlock(_textField.text); //1 [self.navigationController popToRootViewControllerAnimated:YES];}

這樣我們就可以在想要獲取數據回調的地方,也就 A 的視圖中調用 block:

// AViewController.m- (IBAction)push:(id)sender { BViewController *bVC = [self.storyboard instantiateViewControllerWithIdentifier:@"BViewController"]; bVC.callBackBlock = ^(NSString *text){ // 1  NSLog(@"text is %@",text);  self.label.text = text; }; [self.navigationController pushViewController:bVC animated:YES];}

代碼 1 中,通過對回調將 B 中的數據傳遞到代碼塊中,并賦值給 A中的 label,實現了整個回調過程。

上例是通過將 block 直接賦值給 block 屬性,也可以通過方法參數的方式傳遞 block 塊。

關于 Block 的疑惑

到目前為止,一切看起來都很美好(如果你照著上面的例子做的話),功能正常, A 視圖中也獲取到數據了。但是某些人可能就要說了,你的代碼有問題,你的思路有問題,你這是誤人子弟。

是的,代碼的確還有問題,第一個問題就是循環引用的問題,在 A 視圖的block 代碼塊中:

bVC.callBackBlock = ^(NSString *text){  NSLog(@"text is %@",text);    self.label.text = text;   };

代碼 self.label.text = text; ,在 Block 中引用 self ,也就是 A ,而 A 創建并引用了 B ,而 B 引用 callBackBlock,此時就形成了一個循環引用,而編譯器也不會報任何錯誤,我們需要非常小心這個問題(面試百分百問到我會亂說?)。此時我們通常的解決方法是使用弱引用來解除這個循環:

 __weak AViewController *weakSelf = self; bVC.callBackBlock = ^(NSString *text){   NSLog(@"text is %@",text); //  self.label.text = text;   weakSelf.label.text = text; };

第二個問題是我自己對 Block 的理解不到位,我們都知道 Block 能截取自動變量,并且是不能在 Block 塊中進行修改的(除非用__block修飾符),但是很明顯 weakSelf.label.text的值被修改了,并且沒有用__block修飾符, 這是為什么呢?因為 label 是個全局變量,而如果像如下的局部變量 a 是不能修改的,編譯器也會報錯:


局部變量

通過這個小例子發現的兩個問題,也算是值得了。

Block 為什么能實現神奇的回調

在這里我不會說什么實現原理,僅僅是個人對 Block 能實現神奇回調的理解,有錯誤的地方請大家指出。

在先前使用 Block 的過程中,雖然會使用,但是總是有一個疑惑,簡單說來就是:

為什么在 A 中的 block 塊能調用到 B 中的數據?

回顧一下我們在 B 中所實現的代碼,不外乎定義了一個 Block 變量,并在適當的時候傳入參數,那么為什么在調用了  self.callBackBlock(_textField.text) 之后,值就神奇傳到了 A 中的 Block 塊了呢?

通過整理使用的過程,我發現是我們的思維陷入了誤區(可能是我個人),我們認為在 B 中傳入 _textField.text 參數之后, A 中的 Block 塊就可以獲取到值。雖然思路是對的,但其實是不完整,導致我們形成了回調的數據是通過某種底層實現傳遞過去的錯覺,這就使得我們認為這不需要深究。

事實是,通過簡單的整理我們可以發現完整的回調流程應該是這樣的:


回調流程

block 代碼塊賦值給 bVC.callBackBlock,此時 callBackBlock 的指針就指向這個代碼塊。

調用 callBackBlock(NSString *text)

由于 callBackBlock 的指針是指向 A 中的 block 代碼塊,因此執行代碼塊的代碼,實現回調。

很顯然之前我忽略了代碼塊賦值給 callBackBlock 的這個操作(羞愧)。

現在再通過一段代碼可以更清晰地理解這個原理:

 bVC.callBackBlock = ^(NSString *text){ //1  NSLog(@"text is %@",text); }; bVC.callBackBlock = ^(NSString *text){ //2  NSLog(@"text b is %@",text); };

上述代碼中,我們對 callBackBlock進行了兩次賦值,結果會怎么樣呢?


two block

可以看出來,Block 的回調只對代碼 2 生效,因為callBackBlock的指針最后指向了代碼 2 的代碼塊。所以并沒有什么神奇的魔法,也沒什么隱藏的底層機制(這里指的是方便理解的底層)讓你可以帶著疑惑去使用它。

總結

我這個人學習方法,總結起來就是看到新技術,先在自己的代碼里跑一遍,能跑通,并且使用起來沒有什么難度,就基本不會深究了。但是自我反思過,這樣的學習方法是很不對的,寫代碼不能不求甚解,如果想要有所突破,不想局限于碼農,一定要深入探究一下實現的機制,最起碼要保證不帶著疑惑去使用。以上就是這篇文章的全部內容,希望能對大家的學習或者工作帶來一定的幫助,如果有疑問大家可以留言交流。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品欧美激情在线播放| 色偷偷av亚洲男人的天堂| 国产男女猛烈无遮挡91| 亚洲国模精品一区| 丝袜亚洲另类欧美重口| 欧美一级淫片videoshd| 91精品国产综合久久久久久蜜臀| 国产成人精品优优av| 日韩在线中文字幕| 国产精品久久久久久久久久ktv| 亚洲夜晚福利在线观看| 国产精自产拍久久久久久蜜| 精品久久久久久中文字幕一区奶水| 亚洲无限乱码一二三四麻| 亚洲天堂日韩电影| 精品中文视频在线| 97超级碰碰人国产在线观看| 欧美韩国理论所午夜片917电影| 精品视频一区在线视频| 成人午夜两性视频| 国产精品自产拍在线观看| 欧美成人午夜剧场免费观看| 7777免费精品视频| 这里只有精品视频在线| 国产精品九九久久久久久久| 黑人极品videos精品欧美裸| 久久久精品久久| 欧洲中文字幕国产精品| 日韩激情片免费| 欧美日韩高清在线观看| 成人国内精品久久久久一区| 国产日韩欧美影视| 欧美国产日本在线| 国产精自产拍久久久久久蜜| 国产精品中文久久久久久久| 日本精品久久久久影院| 亚洲精品第一页| 精品成人69xx.xyz| 欧美裸体xxxx极品少妇软件| 欧美大片免费观看在线观看网站推荐| 亚洲精品久久久久久久久久久久久| 精品少妇一区二区30p| 国产日韩欧美一二三区| 77777少妇光屁股久久一区| 8090成年在线看片午夜| 欧美在线免费观看| 国产精品91久久久| 热久久免费视频精品| 欧美激情网站在线观看| 国产精品嫩草影院一区二区| 国产免费一区二区三区香蕉精| 国产精品香蕉av| 国产成人精品av| 日韩av一区在线观看| 亚洲美女中文字幕| 91精品国产777在线观看| 国产日韩欧美自拍| 欧美亚洲在线视频| 成人在线中文字幕| 欧美一区二区三区图| 欧美视频一二三| 精品久久久久久亚洲精品| 亚洲电影天堂av| 38少妇精品导航| 国产精品日韩电影| 午夜精品一区二区三区视频免费看| 日韩中文字幕在线播放| 欧美性jizz18性欧美| 成人激情在线播放| 国产精品色悠悠| 丝袜情趣国产精品| 日韩在线免费视频观看| 久久亚洲春色中文字幕| 中文字幕亚洲综合久久筱田步美| 韩国19禁主播vip福利视频| 成年无码av片在线| 91网站在线免费观看| 欧美在线视频免费观看| 在线观看国产欧美| 日韩国产激情在线| 成人激情视频在线播放| 日韩日本欧美亚洲| 国内精品久久久久影院 日本资源| 久久综合88中文色鬼| 欧美精品一区三区| 国产成人综合精品| 日韩**中文字幕毛片| 欧美激情在线观看视频| 欧美日韩国产中文字幕| 日韩有码在线视频| 国产视频丨精品|在线观看| 国产精品男人的天堂| 国产综合在线观看视频| 国产精品美女主播在线观看纯欲| 欧美日韩免费在线观看| 久久九九有精品国产23| 亚洲成年人在线播放| 亚洲性猛交xxxxwww| 91久久久久久国产精品| 国产婷婷成人久久av免费高清| 欧美性xxxx极品高清hd直播| 精品国内产的精品视频在线观看| 亚洲国产精品免费| 欧美精品18videos性欧美| 精品久久中文字幕| 久久久久一本一区二区青青蜜月| 91精品国产91久久| 国产精品久久久久影院日本| 国产精品网红福利| 日韩免费观看在线观看| 一区二区三区天堂av| 国外成人性视频| 久久这里有精品视频| 国产精品久久久久高潮| 激情成人在线视频| 欧美精品激情在线观看| 成人性生交大片免费看小说| 国产精品网站视频| 日韩视频免费在线| 亚洲少妇中文在线| 日韩成人在线免费观看| 欧美日韩国产一区二区三区| 欧美区在线播放| 78m国产成人精品视频| 国产一区二区日韩精品欧美精品| 韩日欧美一区二区| 正在播放亚洲1区| 色天天综合狠狠色| 日韩免费黄色av| 国产一区二区三区四区福利| 欧美中文在线免费| 97视频人免费观看| 精品国产福利在线| 亚洲精品国产精品国自产在线| 欧美日韩国产中文精品字幕自在自线| 91精品国产777在线观看| 国产精品一区二区在线| 色妞一区二区三区| 精品国产自在精品国产浪潮| 亚洲第一免费播放区| 精品中文字幕在线2019| 欧美最猛性xxxxx免费| 97视频在线观看免费高清完整版在线观看| 高潮白浆女日韩av免费看| 欧美丝袜一区二区| 精品亚洲永久免费精品| 亚洲国产精品福利| 亚洲大胆人体在线| 亚洲精品短视频| 伊人久久男人天堂| 国产拍精品一二三| 欧美xxxx14xxxxx性爽| 国产精品免费电影| 疯狂欧美牲乱大交777| 午夜免费在线观看精品视频| 91极品女神在线| 国产精品成人av性教育| 欧美日韩午夜视频在线观看| 欧美激情一区二区三区高清视频| 国产精品三级在线| 欧美在线激情网| 欧美日韩日本国产| 最新69国产成人精品视频免费| www.久久久久久.com|