最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

iOS中Block的回調(diào)使用和解析詳解

 更新時(shí)間:2016年09月25日 14:16:24   作者:純潔的小袋子  
剛剛進(jìn)入iOS開發(fā)行業(yè),發(fā)現(xiàn)開發(fā)中要用到大量的block回調(diào),由此可見它的重要性。本文主要講的是 Block 回調(diào)的使用,以及 Block 是如何實(shí)現(xiàn)這種神奇的回調(diào)兩部分來講的,下面來一起看看吧。

Block 回調(diào)實(shí)現(xiàn)

先跟著我實(shí)現(xiàn)最簡單的 Block 回調(diào)傳參的使用,如果你能舉一反三,基本上可以滿足了 OC 中的開發(fā)需求。已經(jīng)實(shí)現(xiàn)的同學(xué)可以跳到下一節(jié)。

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

有兩個(gè)視圖控制器 A 和 B,現(xiàn)在點(diǎn)擊 A 上的按鈕跳轉(zhuǎn)到視圖 B ,并在 B 中的textfield 輸入字符串,點(diǎn)擊 B 中的跳轉(zhuǎn)按鈕跳轉(zhuǎn)回 A ,并將之前輸入的字符串

顯示在 A 中的 label 上。也就是說 A 視圖中需要回調(diào) B 視圖中的數(shù)據(jù)。

想不明白的同學(xué)可以看一看最終實(shí)現(xiàn)的效果圖:

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

首先,我們需要定義兩個(gè)試圖控制器 AViewController BViewController,現(xiàn)在我們需要思考一下,Block 應(yīng)該在哪里定義呢?

我們可以簡單地這樣思考,需要回調(diào)數(shù)據(jù)的是 A 視圖,那么 Block 就應(yīng)該在 B 中定義,用于獲取傳入回調(diào)數(shù)據(jù)。

因此我們在 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 中,使用這個(gè)別名定義一個(gè) Block 類型的變量 callBackBlock。

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

//BViewController.m

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

這樣我們就可以在想要獲取數(shù)據(jù)回調(diào)的地方,也就 A 的視圖中調(diào)用 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 中,通過對回調(diào)將 B 中的數(shù)據(jù)傳遞到代碼塊中,并賦值給 A中的 label,實(shí)現(xiàn)了整個(gè)回調(diào)過程。

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

關(guān)于 Block 的疑惑

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

是的,代碼的確還有問題,第一個(gè)問題就是循環(huán)引用的問題,在 A 視圖的block 代碼塊中:

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

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

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

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


局部變量

通過這個(gè)小例子發(fā)現(xiàn)的兩個(gè)問題,也算是值得了。

Block 為什么能實(shí)現(xiàn)神奇的回調(diào)

在這里我不會(huì)說什么實(shí)現(xiàn)原理,僅僅是個(gè)人對 Block 能實(shí)現(xiàn)神奇回調(diào)的理解,有錯(cuò)誤的地方請大家指出。

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

為什么在 A 中的 block 塊能調(diào)用到 B 中的數(shù)據(jù)?

回顧一下我們在 B 中所實(shí)現(xiàn)的代碼,不外乎定義了一個(gè) Block 變量,并在適當(dāng)?shù)臅r(shí)候傳入?yún)?shù),那么為什么在調(diào)用了  self.callBackBlock(_textField.text) 之后,值就神奇?zhèn)鞯搅?A 中的 Block 塊了呢?

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

事實(shí)是,通過簡單的整理我們可以發(fā)現(xiàn)完整的回調(diào)流程應(yīng)該是這樣的:


回調(diào)流程

block 代碼塊賦值給 bVC.callBackBlock,此時(shí) callBackBlock 的指針就指向這個(gè)代碼塊。

調(diào)用 callBackBlock(NSString *text)

由于 callBackBlock 的指針是指向 A 中的 block 代碼塊,因此執(zhí)行代碼塊的代碼,實(shí)現(xiàn)回調(diào)。

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

現(xiàn)在再通過一段代碼可以更清晰地理解這個(gè)原理:

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

上述代碼中,我們對 callBackBlock進(jìn)行了兩次賦值,結(jié)果會(huì)怎么樣呢?


two block

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

總結(jié)

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

相關(guān)文章

  • iOS開發(fā)retina屏幕下的點(diǎn)與像素關(guān)系詳解

    iOS開發(fā)retina屏幕下的點(diǎn)與像素關(guān)系詳解

    這篇文章主要為大家介紹了iOS開發(fā)retina屏幕下的點(diǎn)與像素關(guān)系詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • iOS實(shí)時(shí)錄音和播放功能

    iOS實(shí)時(shí)錄音和播放功能

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)時(shí)錄音和播放功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • iOS中Cell的Section展開和收起的示例代碼

    iOS中Cell的Section展開和收起的示例代碼

    本篇文章主要介紹了iOS中Cell的Section展開和收起的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • iOS 無卡頓同時(shí)使用圓角、陰影和邊框的實(shí)現(xiàn)

    iOS 無卡頓同時(shí)使用圓角、陰影和邊框的實(shí)現(xiàn)

    這篇文章主要介紹了iOS 無卡頓同時(shí)使用圓角、陰影和邊框的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • iOS彈幕開發(fā)中遇到的問題匯總

    iOS彈幕開發(fā)中遇到的問題匯總

    最近做項(xiàng)目的時(shí)候需要實(shí)現(xiàn)彈幕這個(gè)功能, 雖然感覺實(shí)現(xiàn)起來也不是很復(fù)雜,但還是遇到了一些問題,下面這篇文章主要給大家總結(jié)介紹了在iOS彈幕開發(fā)中遇到的問題,文中將解決的方法介紹的非常詳細(xì),需要的朋友可以參考下。
    2018-01-01
  • iOS撥打電話的3種實(shí)現(xiàn)方式

    iOS撥打電話的3種實(shí)現(xiàn)方式

    這篇文章主要介紹了iOS撥打電話的3種實(shí)現(xiàn)方式 ,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2018-06-06
  • React Native學(xué)習(xí)教程之自定義NavigationBar詳解

    React Native學(xué)習(xí)教程之自定義NavigationBar詳解

    這篇文章主要給大家介紹了關(guān)于React Native學(xué)習(xí)教程之自定義NavigationBar的相關(guān)資料,文中通過是示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10
  • iOS各種ViewController控制器使用示例完整介紹

    iOS各種ViewController控制器使用示例完整介紹

    這篇文章主要為大家介紹了iOS各種ViewController控制器使用示例完整介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • IOS獲取當(dāng)前版本號(hào) Bundle ID等信息的方法詳解

    IOS獲取當(dāng)前版本號(hào) Bundle ID等信息的方法詳解

    這篇文章主要介紹了IOS獲取當(dāng)前版本號(hào) Bundle ID等信息的方法詳解的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • iOS中謂詞(NSPredicate)的基本入門使用教程

    iOS中謂詞(NSPredicate)的基本入門使用教程

    這篇文章主要給大家介紹了關(guān)于iOS中謂詞(NSPredicate)的基本入門使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01

最新評論

彰化县| 衡东县| 建平县| 安西县| 枣强县| 施甸县| 金乡县| 明光市| 集贤县| 手机| 丘北县| 伊宁市| 舒城县| 罗平县| 新乡市| 当阳市| 杂多县| 雷山县| 二连浩特市| 专栏| 天全县| 望都县| 铁力市| 临武县| 莎车县| 黔西县| 彭山县| 金堂县| 民权县| 县级市| 喀喇沁旗| 西丰县| 太仆寺旗| 鸡泽县| 庆安县| 龙井市| 温泉县| 城口县| 彰武县| 汕头市| 逊克县|