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其實,這是因為oc是一種執行時語言,我們寫的oc**最終都是要轉換成c語言的**去執行的。我們通過執行時**可以知道,系統會把使用到的外部變數通過引數列表傳遞給block,也就變成了block內部的區域性變數,所以可以使用。)viewdidload ;
}
而在傳遞的時候,對於基本資料型別的外部變數來說,系統預設傳遞的僅僅是值,也就是說這個區域性變數是不能修改的。如果想修改值,會使用__block來修飾這個變數。這樣一來,系統在傳遞的時候,傳的就是外部變數的位址,這樣我們就可以修改值了。
__block int a = 10;//對於物件型別,傳遞的是位址,同時預設對該物件進行了一次強引用。系統進行了強引用,而他又對該物件的記憶體管理袖手旁觀,也就是說,他只做了強引用,但是沒有做釋放操作。這個時候就會造成記憶體洩漏。所以,我們在使用物件的時候,在mrc下,都會使用__block修飾,在arc下,使用__weak修飾,這樣一來,系統在傳遞的時候就不會對該物件進行強引用,避免了記憶體洩漏。用__block修飾之後,系統會傳遞a的位址(&a)
_block = ^;
1 - (void最後,說說block的通訊。說到物件之間的通訊,我們一般有三種方式:**、block、通知。)viewdidload ;
1213 }
什麼是通訊呢?就是兩個物件之間,你讓我幹什麼什麼,我讓你幹什麼什麼。
舉個例子,現在有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指標 返回型別 可省略 引數型別 引數 沒有引數可省...