block系列1-block使用

1.使用Blocks


(1)block概念

Blocks是帶有自動變了(局部變量)的匿名函數(shù)抚芦。其寫法遵循BN范式

^ 返回值類型 參數(shù)列表 表達(dá)式

返回值類型可省略,參數(shù)列表亦可省略履怯。可以定一個Blocks變量來獲得匿名函數(shù)的使用權(quán)

int (^blk)(int) = ^(int count){return count+1};

我們可以作為參數(shù)傳遞Blocks變量,也可以返回Blocks類型變量,也可以使用typedef定義更方便使用Blocks變量

void func(int (^blk)(int)){}

int (^func())(int){
    return ^(int count){return count+1};
}

typedef int (^blc_t)(int);
  • block的代碼是內(nèi)聯(lián)的冗懦,效率高于函數(shù)調(diào)用
  • block對于外部變量默認(rèn)是只讀屬性,要在block內(nèi)修改外部變量需要添加_block關(guān)鍵字修飾
  • block被Objective-C看成是對象處理

block會捕獲在其定義時的變量值谬运,變量修改后并不會影響block中使用的變量隙赁。

{
    int a = 10;
    int (^blc)(int) = int ^(int count){return count+a;};
    a++;
    NSLog(@"%@",blc(5));//打印15,而不是16
}

變量的復(fù)制關(guān)系如下

block外變量引用梆暖,默認(rèn)是復(fù)制到block內(nèi)的readonly變量

[站外圖片上傳中...(image-7c89d1-1524555790555)]

對于用__ block修飾的外部變量引用伞访,block復(fù)制其引用地址來實現(xiàn)訪問

[站外圖片上傳中...(image-a85bf0-1524555790555)]

(2)block常見用法:

  1. 局部位置聲明一個Block型的變量

    return_type (^blockName)(var_type) = ^return_type (var_type varName) {
        // ...
    };
    blockName(var);
    
  2. @interface聲明Block型屬性

    @property(nonatomic, copy)return_type (^blockName) (var_type);
    
  3. Block型作為形參

    - (void)yourMethod:(return_type (^)(var_type))blockName;
    
  4. 內(nèi)聯(lián)用法,定義后立即調(diào)用,不常用

    ^return_type (var_type varName)
    {
        //...
    }(var);
    
  5. 遞歸調(diào)用

    使用__block避免循環(huán)引用問題轰驳。

    __block return_type (^blockName)(var_type) = [^return_type (var_type varName)
    {
        if (returnCondition)
        {
            blockName = nil;
            return;
        }
        // ...
        // 【遞歸調(diào)用】
        blockName(varName);
    } copy];
    
    【初次調(diào)用】
    blockName(varValue);
    
  6. 作為返回值

    - (return_type(^)(var_type))methodName
    {
        return ^return_type(var_type param) {
            // ...
        };
    }
    

    ?

2.block原理


(1)數(shù)據(jù)結(jié)構(gòu)定義

block的數(shù)據(jù)結(jié)構(gòu)定義如下

[站外圖片上傳中...(image-894ad2-1524555790555)]

結(jié)構(gòu)體定義如下

#define BLOCK_DESCRIPTOR_1 1
struct Block_descriptor_1 {
    unsigned long int reserved;
    unsigned long int size;
};
struct Block_layout {
    void *isa;
    volatile int flags; // contains ref count
    int reserved; 
    void (*invoke)(void *, ...);
    struct Block_descriptor_1 *descriptor;
    // imported variables
};
//Block-private.h

對于每個參數(shù)解釋如下

  1. isa: 對象指針
  2. flags: 記錄block的一些附加信息咐扭,包括引用計數(shù)
  3. reserved: 保留變量。
  4. invoke: 函數(shù)指針滑废,指向block函數(shù)實現(xiàn)地址蝗肪。
  5. descriptor:附加信息描述
//falgs bit位描述如下
enum {
    BLOCK_DEALLOCATING =      (0x0001),  // runtime
    BLOCK_REFCOUNT_MASK =     (0xfffe),  // runtime
    BLOCK_NEEDS_FREE =        (1 << 24), // runtime
    BLOCK_HAS_COPY_DISPOSE =  (1 << 25), // compiler
    BLOCK_HAS_CTOR =          (1 << 26), // compiler: helpers have C++ code
    BLOCK_IS_GC =             (1 << 27), // runtime
    BLOCK_IS_GLOBAL =         (1 << 28), // compiler
    BLOCK_USE_STRET =         (1 << 29), // compiler: undefined if !BLOCK_HAS_SIGNATURE
    BLOCK_HAS_SIGNATURE  =    (1 << 30)  // compiler
};

從枚舉變量的定義可以看出flags的bit位作用,第0位表示釋放內(nèi)存標(biāo)志蠕趁,1-23bit作為引用計數(shù)值薛闪,24-31略過。

在OC中有三種block

  1. _NSConcreteGlobalBlock 全局的靜態(tài) block俺陋,不會訪問任何外部變量豁延。
  2. _NSConcreteStackBlock 保存在棧中的 block,當(dāng)函數(shù)返回時會被銷毀,ARC下不適用腊状。
  3. _NSConcreteMallocBlock 保存在堆中的 block诱咏,當(dāng)引用計數(shù)為 0 時會被銷毀。

下篇文章講解不同block的實現(xiàn)方式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缴挖,一起剝皮案震驚了整個濱河市袋狞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖苟鸯,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件同蜻,死亡現(xiàn)場離奇詭異,居然都是意外死亡早处,警方通過查閱死者的電腦和手機(jī)湾蔓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來砌梆,“玉大人默责,你說我怎么就攤上這事∠贪” “怎么了傻丝?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長诉儒。 經(jīng)常有香客問我葡缰,道長,這世上最難降的妖魔是什么忱反? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任泛释,我火速辦了婚禮,結(jié)果婚禮上温算,老公的妹妹穿的比我還像新娘怜校。我一直安慰自己,他們只是感情好注竿,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布茄茁。 她就那樣靜靜地躺著,像睡著了一般巩割。 火紅的嫁衣襯著肌膚如雪裙顽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天宣谈,我揣著相機(jī)與錄音愈犹,去河邊找鬼。 笑死闻丑,一個胖子當(dāng)著我的面吹牛漩怎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嗦嗡,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼勋锤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了侥祭?” 一聲冷哼從身側(cè)響起叁执,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤茄厘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后徒恋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚕断,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡欢伏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年入挣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硝拧。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡径筏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出障陶,到底是詐尸還是另有隱情滋恬,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布抱究,位于F島的核電站恢氯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鼓寺。R本人自食惡果不足惜勋拟,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望妈候。 院中可真熱鬧敢靡,春花似錦、人聲如沸苦银。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幔虏。三九已至纺念,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間想括,已是汗流浹背柠辞。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留主胧,地道東北人叭首。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像踪栋,于是被迫代替她去往敵國和親焙格。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容