{Ws看官網(wǎng)文檔}Block-變量傳遞(二)


  • 寫(xiě)在前面: 翻翻各個(gè)iOS大牛的博客,或者在他們回答新手如何學(xué)習(xí)iOS開(kāi)發(fā)時(shí),"多看,一定要看蘋(píng)果官方文檔"這句話100%會(huì)出現(xiàn)."蘋(píng)果人家是權(quán)威,多少博客都是翻譯一遍罷了""不要啃人家嚼過(guò)的甘蔗".理都懂,然并卵.就結(jié)合自己情況來(lái)說(shuō),之前也看的不多原因有三:
  • 1.中文看著多舒服,人忙忙的,問(wèn)題解決就ok,想那多干啥
  • 2.臥槽,密密麻麻這是啥,看兩行嚇得我電腦都關(guān)上了
  • 3.問(wèn)問(wèn)自己的定位,你是不是一位合格并且有上進(jìn)心的開(kāi)發(fā)者?

其實(shí)對(duì)于大多數(shù)開(kāi)發(fā)者來(lái)說(shuō),入了門(mén)之后,耳濡目染的都會(huì)寫(xiě),認(rèn)識(shí)些英文,所以其實(shí)還是一個(gè)懶,這句話也在說(shuō)自己. 時(shí)光恍恍惚惚時(shí)間就這么沒(méi)了,maybe失去些東西會(huì)讓人突然安靜下來(lái).學(xué)習(xí)iOS一直自己做筆記,翻了翻自己的筆記,有些概念模模糊糊模棱兩可,覺(jué)得是時(shí)候總結(jié)一波了.不想做咸魚(yú)的我也就在這時(shí)候靜下心來(lái),看了一晚上蘋(píng)果官網(wǎng)文檔,對(duì),是一晚上.不會(huì)的單詞右擊Look up, 復(fù)雜些的google.很惡心自己英文下降很多,但是觀后感是:臥槽,這玩意才是武功秘籍好伐, 不管是guide還是一些api說(shuō)明,實(shí)例code,絕逼權(quán)威,個(gè)人也覺(jué)得不會(huì)比一些中博客"翻譯"過(guò)來(lái)的難理解. 一晚上,"soga...原來(lái)是這樣!""這個(gè)這么理解才對(duì)""媽蛋,吃了這么久的二手甘蔗",是我整個(gè)心理活動(dòng).
當(dāng)然夸張了, 只是覺(jué)得一是靜下心來(lái)認(rèn)真那種感覺(jué)很難得,二是官方文檔真的很好.

這個(gè)集我想著自己盡量多的總結(jié)下官方文檔的原文內(nèi)容(不會(huì)大段落的翻譯),帶著自己(如果能幫到你就更好啦), 咱們?nèi)コ砸皇重?!


英文全部來(lái)自官方文檔iOS9.1Document ,如果有錯(cuò)誤,可能是復(fù)制或者打字錯(cuò)誤, 開(kāi)局了:

    1. Blocks Can Capture Values from the Enclosing Scope

(先別急著翻譯,看下下面的這兩個(gè)方法,猜下輸出先.)
As well as containing executable code, a block also has the ability to capture state from its enclosing scope.
If you declare a block literal from within a method, for example, it’s possible to capture any of the values accessible within the scope of that method, like this:

- (void)testMethod {
    int anInteger = 42;
 
    void (^testBlock)(void) = ^{
        NSLog(@"Integer is: %i", anInteger);
    };
 
    testBlock();
}

In this example, anInteger is declared outside of the block, but the value is captured when the block is defined.

Only the value is captured, unless you specify otherwise. This means that if you change the external value of the variable between the time you define the block and the time it’s invoked, like this:

int anInteger = 42;

void (^testBlock)(void) = ^{
    NSLog(@"Integer is: %i", anInteger);
};

anInteger = 84;

testBlock();

the value captured by the block is unaffected. This means that the log output would still show:

Integer is: 42      //輸出是42```
It also means that the block cannot change the value of the original variable, or even the captured value (it’s captured as a const variable).
```objc
這里來(lái)總結(jié)文檔意思: 不僅可以包含可執(zhí)行代碼一樣,block能力超群,可以從封閉范圍內(nèi)獲取值. 
其實(shí)道理很簡(jiǎn)單,答案應(yīng)該有2種: 42 ,84 
42是覺(jué)得,可以的,不過(guò)這里是值傳遞
84覺(jué)得,外面修改了,我里面也用了,有可能吧.

隨后文檔給了解釋: 除非你特殊定義,不然這個(gè)局部變量存在Block中后,后面你修改,它內(nèi)部value是不影響的.
就像const來(lái)修飾一個(gè)變量,讓它只讀!

問(wèn)題來(lái)了,那么怎樣叫特殊定義,怎樣可以修改? 來(lái)接下來(lái)就有解釋了.
  1. Use __block Variables to Share Storage(這個(gè)標(biāo)題自己翻譯下)

If you need to be able to change the value of a captured variable from within a block, you can use the __block storage type modifier on the original variable declaration. This means that the variable lives in storage that is shared between the lexical scope of the original variable and any blocks declared within that scope.

As an example, you might rewrite the previous example like this:

__block int anInteger = 42;

void (^testBlock)(void) = ^{
    NSLog(@"Integer is: %i", anInteger);
};

anInteger = 84;

testBlock();

Because anInteger is declared as a __block variable, its storage is shared with the block declaration. This means that the log output would now show:

Integer is: 84   //這里輸出就成84了
也就是說(shuō),用__block修飾變量,外部修改了這個(gè)變量,那么block里用得時(shí)候,就得注意了,值就變了.
用歪果仁的原文就是,Because anInteger is declared as a __block variable,
its storage is shared with the block declaration,分享給了你,這思維咋翻譯嘛....
也就可以理解為,指針傳遞,帶了__block這個(gè)修飾變量,外面修改,里面也會(huì)改

It also means that the block can modify the original value, like this:
(在看看這個(gè):)

__block int anInteger = 42;

  void (^testBlock)(void) = ^{
      NSLog(@"Integer is: %i", anInteger);
      anInteger = 100;
  };

  testBlock();
  NSLog(@"Value of original variable is now: %i", anInteger);
This time, the output would show:

輸出分別是:
Integer is: 42
Value of original variable is now: 100

  • 也就意味者,外部修改變量,會(huì)影響block調(diào)用時(shí)它的值,同時(shí)block內(nèi)部也可以修改,有執(zhí)行順序,猜猜那么下段怎么輸出.
- (void)text {
    
    __block int a = 10;
    
    void(^block)() = ^void() {
        a = 20;   //先修改a
        NSLog(@"a = %d",a);
        
    };
    
    block();
    
    NSLog(@" new a = %d",a);
    
}

//沒(méi)錯(cuò),內(nèi)部是按順序執(zhí)行的,   a = 20   ,new a = 20
  • 我也很疑惑,為什么加上_ block就可以了,是不是變量作用域的問(wèn)題. 那么我就不加 _block,而是把a(bǔ)修飾成全局的試試? 加上static是什么效果? 自己去試試吧,下面是結(jié)果.
int a = 10;

- (void)text {
    
    
    void(^block)() = ^void() {
        a = 30;
        NSLog(@"%d",a);
        
    };
        a = 20;
    
    block();
    
    NSLog(@" new a = %d",a); 
  /* 輸出a = 30; new a = 30; 所以執(zhí)行順序就明白了:
     先到a = 20; 然后進(jìn)block
  */
--------------------------------------------
- (void)text2 {
    
    static int a = 5;
    void(^block)() = ^void() {
        
        NSLog(@"%d",a);
        
    };
    a = 20;
    
    block();
    
    NSLog(@" new a = %d",a);
      /* 輸出a = 20; new a = 20; 所以執(zhí)行順序就明白了:
     先到a = 20; 然后進(jìn)block
  */
------------------------------
- (void)text3 {
    
    static int a = 5;
    void(^block)() = ^void() {
        a = 30;
        NSLog(@"%d",a);
        
    };
    a = 20;
    
    block();
    
    NSLog(@" new a = %d",a);
    //輸出 a = 30;  new a = 30;
}

所以蘋(píng)果這里說(shuō)__block的意義在于,1. 在一個(gè)函數(shù)中,它不僅可以保存代碼塊
更是可以跳出那個(gè){},獲取外面的值  2.加上__block后,更是在block塊兒內(nèi)獲取外面值得時(shí)候,先修改,再存入,
同時(shí)block內(nèi)可以修改這個(gè)變量值,這里思想就不會(huì)禁錮在變量的作用域上.而是說(shuō)Block的特性
所以不糾結(jié)其他的,總結(jié)block下就是兩種傳遞:
1.值傳遞
2.指針傳遞.  為啥這么叫,用clang再編譯下,然后查找對(duì)應(yīng)傳遞,就會(huì)明白啦! 
不加__block,傳的是值
加上__block,是指針
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 11,039評(píng)論 0 23
  • 我覺(jué)得所謂的結(jié)束,不過(guò)是暫時(shí)告一段落,并無(wú)太大意義,就如同活著一樣。并非因?yàn)橛辛私Y(jié)束,過(guò)程才有意義,而是為了便宜的...
    愛(ài)斯基摩人we閱讀 946評(píng)論 0 0
  • 人在一定的年齡段會(huì)有一定的變化,等你過(guò)了那個(gè)年齡段,就會(huì)覺(jué)得自己以前多么可笑
    HANZIQIANG閱讀 60評(píng)論 0 1
  • 愿你三冬暖,愿你春不寒; 愿你天黑有燈,下雨有傘; 愿你一路上,有良人陪伴; 愿你翻山越嶺都有人想念; 愿你一路風(fēng)...
    灰兮閱讀 306評(píng)論 0 0
  • 這個(gè)系列的文章是我最想寫(xiě)的東西之一,卻也是最不會(huì)寫(xiě)的東西。創(chuàng)作它的想法萌發(fā)于某次國(guó)際處值班,無(wú)聊的我刷知乎刷到了田...
    冰鎮(zhèn)冰水閱讀 498評(píng)論 0 1

友情鏈接更多精彩內(nèi)容