block屬性的宣告,首先需要用copy修飾符,因為只有copy後的block才會在堆中,棧中的block的生命週期是和棧繫結的。
另乙個需要注意的問題是關於執行緒安全,在宣告block屬性時需要確認「在呼叫block時另乙個執行緒有沒有可能去修改block?」這個問題,如果確定不會有這種情況發生的話,那麼block屬性宣告可以用nonatomic。如果不肯定的話(通常情況是這樣的),那麼你首先需要宣告block屬性為atomic,也就是先保證變數的原子性(objective-c並沒有強制規定指標讀寫的原子性,c#有)。
比如這樣乙個block型別:
typedef
void(^myblock)(int);
屬性宣告:
@property (copy) myblock myblock;
這裡arc和非arc宣告都是一樣的,當然注意在非arc下要release block。
但是,有了atomic來保證基本的原子性還是沒有達到執行緒安全的,接著在呼叫時需要把block先賦值給本地變數,以防止block突然改變。因為如果不這樣的話,即便是先判斷了block屬性不為空,在呼叫之前,一旦另乙個執行緒把block屬性設空了,程式就會crash,如下**:
if (self.myblock)
所以正確的**是(arc):
myblocktype block = self.myblock;
//block現在是本地不可變的
if (block)
在非arc下則需要手動retain一下,否則如果屬性被置空,本地變數就成了野指標了,如下**:
//非arc
myblocktype block = [self.myblock retain];
if (block)
[block release];
迴圈引用是另乙個使用block時常見的問題。
在arc下,由於__block抓取的變數一樣會被block retain,所以必須用弱引用才可以解決迴圈引用問題,ios 5之後可以直接使用__weak,之前則只能使用__unsafe_unretained了,__unsafe_unretained缺點是指標釋放後自己不會置空。示例**:
//ios 5之前可以用__unsafe_unretained
//__unsafe_unretained typeof(self) weakself = self;
__weak typeof(self) weakself = self;
self
.myblock = ^(int paramint)
;
//非arc
__block typeof(self) weakself = self;
self.myblock = ^(int paramint)
;
iOS 開發,混合使用 ARC 和非ARC
前提知識 arc automatic reference counting,自動引用計數 在開發 ios 3 以及之前的版本的專案時我們要自己負責使用引用計數來管理記憶體,比如要手動 retain release autorelease 等,而在其後的版本可以使用 arc,讓系統自己管理記憶體。問題...
Block在ARC和非ARC中的使用
1 block是事先封裝好的一段 快,在需要的時候呼叫block執行 block底層是指向結構體的指標,編譯器會將block的內部 生成c語言對應的函式 2 block預設是存放在棧中的 開發人員不需要管理記憶體 儲存在棧中的block不會對引用的物件進行retain 3 非arc 對block進行...
ARC與非ARC混用
隨著arc管理記憶體技術的日漸成熟,人們慢慢傾向於在自己的專案裡使用arc。由於原先一直都是手動管理記憶體的,所以就要考慮怎麼樣在非arc的工程裡用使用arc進行編譯的檔案 類庫。好在這樣的混用十分的簡單。只要對相應的檔案進行一項簡單的設定就成。操作步驟如下 1 選擇專案中的targets,選中你所...