iOS開發之 block的使用 詳解

2021-08-07 19:13:00 字數 2472 閱讀 4951

block**塊主要用於物件之間的通訊(反向傳值和方法傳遞)。

首先,我們從記憶體管理方面來了解一下block

block:我們稱**塊,他類似乙個方法。而每乙個方法都是在被呼叫的時候從硬碟到記憶體,然後去執行,執行完就消失,所以,方法的記憶體不需要我們管理,也就是說,方法是在記憶體的棧區。所以,block不像oc中的類物件(在堆區),他也是在棧區的。如果我們使用block作為乙個物件的屬性,我們會使用關鍵字copy修飾他,因為他在棧區,我們沒辦法控制他的消亡,當我們用copy修飾的時候,系統會把該 block的實現拷貝乙份到堆區,這樣我們對應的屬性,就擁有的該block的所有權。就可以保證block**塊不會提前消亡。

1

#import

"lbs_a_viewcontroller.h"2

3 typedef void(^myblock)(void);//

block寫法比較特殊,一般重新命名一下45

@inte***ce

lbs_a_viewcontroller ()

6 @property (nonatomic,copy)myblock block;//

定義乙個myblock屬性

7@end89

@implementation

lbs_a_viewcontroller

1011 - (void

)viewdidload ;

19//

賦值給屬性_block 此時就完成了copy _block指標指向堆中一塊記憶體(存放的是block的實現**),_block就一直擁有了**塊的使用權,直到 lbs_a_viewcont roller物件消亡。

20 _block =block;

}

當然,一般我們不會這樣寫,block的實現都是在另乙個類的物件中實現。

其次,在block的實現部分要注意一些事情

我們在實現block的時候,一般都會使用到外部(block大括號之外)變數。我們知道,區域性變數(非靜態)是不能在外部使用的,而block又類似是乙個方法,那他為什麼可以使用外部變數呢。

- (void

)viewdidload ;

}

其實,這是因為oc是一種執行時語言,我們寫的oc**最終都是要轉換成c語言的**去執行的。我們通過執行時**可以知道,系統會把使用到的外部變數通過引數列表傳遞給block,也就變成了block內部的區域性變數,所以可以使用。

而在傳遞的時候,對於基本資料型別的外部變數來說,系統預設傳遞的僅僅是值,也就是說這個區域性變數是不能修改的。如果想修改值,會使用__block來修飾這個變數。這樣一來,系統在傳遞的時候,傳的就是外部變數的位址,這樣我們就可以修改值了。

__block int a = 10;//

用__block修飾之後,系統會傳遞a的位址(&a)

_block = ^;

對於物件型別,傳遞的是位址,同時預設對該物件進行了一次強引用。系統進行了強引用,而他又對該物件的記憶體管理袖手旁觀,也就是說,他只做了強引用,但是沒有做釋放操作。這個時候就會造成記憶體洩漏。所以,我們在使用物件的時候,在mrc下,都會使用__block修飾,在arc下,使用__weak修飾,這樣一來,系統在傳遞的時候就不會對該物件進行強引用,避免了記憶體洩漏。

1 - (void

)viewdidload ;

1213 }

最後,說說block的通訊。說到物件之間的通訊,我們一般有三種方式:**、block、通知。

什麼是通訊呢?就是兩個物件之間,你讓我幹什麼什麼,我讓你幹什麼什麼。

舉個例子,現在有a和b兩個物件,其中a物件包含b物件,a如果想讓b幹什麼,a只需要給b乙個訊息[b xiaoxi],而此時,如果b物件想讓a物件幹什麼事情呢,肯定是希望是給a乙個訊息[a xiaoxi],但是b中沒有a物件啊。

那我們能不能給b乙個屬性是a物件呢,讓b也包含a?

顯然不行,第一,b物件中的a物件不是 包含b物件的那個a物件,第二 ,你包含我 我包含你 很可能會造成迴圈引用,最後兩個物件都釋放不了,造成記憶體洩漏。

此時的解決方案是使用**,a包含b物件,當建立b物件的時候,a就把自己設為b的**。那如果b給他的**發訊息,就能保證是包含他的那個a物件去接收訊息了。同時,**屬性我們都是使用關鍵字weak,就是為了避免迴圈引用。

而block和**的使用是一樣的,只不過相對簡單,不用制定協議、寫**方法。同時效率更高。

而通知呢,更靈活,發乙個通知,誰都能註冊接收通知,然後做事情。

那什麼時候使用**、什麼時候使用block、什麼時候使用通知呢?

在使用**和block的時候,我們可能意識到了乙個事情,就是通訊的兩個物件之間,一定是有關係的(a包含b  或者 b包含a),不然怎麼設定**,怎麼實現別的物件的block。所以,當兩個需要通訊的物件之間有包含關係的時候,考慮**和block。比如,上面的a和b物件,如果b想讓a幹不止一件事情,就用**。如果就是一件事情,沒必要又制訂協議,有些**方法,太麻煩,此時可以考慮使用block。

iOS開發之block解析

1.block的本質是乙個objective c的物件。為什麼這麼說?在objective c中。runtime會在執行時依據物件的isa指標的指向,來度額定這個物件的型別。也能夠覺得乙個物件。它具有isa指標。就是乙個oc物件 2.你怎麼知道block有isa指標呢。我們能夠通過clang命令將來...

iOS開發中block的使用

block簡介 block的實際行為和function很像,最大的差別是在可以訪問同乙個scope的變數值。block實體形式如下 傳入引數列 block實體開頭是 接著是由小括號所包起來的引數列 比如 int a,int b,int c 行為主體由大括號包起來,專有名字叫做block litera...

iOS開發 Block詳解

block是乙個非常有特色的語法,它可以把乙個 塊作為乙個變數來儲存,也可以通過函式傳遞變數,然後讓其他的物件來執行這一 塊。可以儲存傳遞並在其他地方執行的 塊,這是我對block的理解,也是我覺得block最吸引我的地方。直接定義 返回block指標 返回型別 可省略 引數型別 引數 沒有引數可省...