block作為類的屬性時用copy

2022-08-04 10:33:12 字數 1623 閱讀 5976

block屬性的宣告,首先需要用copy修飾符,因為只有copy後的block才會在堆中,棧中的block的生命週期是和棧繫結的

《棧 :由系統維護的區域性變數 是存在棧上的,其生命週期隨函式的生命週期》

《堆 :由程式設計師申請空間位址,由程式設計師手動釋放,生命週期受到程式設計師控制》

使用retain也可以,因為block的retain行為預設是用copy的行為實現的,block變數預設是宣告為棧變數的,為了能夠在block的宣告域外使用,所以要把block拷貝(copy)到堆,所以說為了block屬性宣告和實際的操作一致,最好宣告為copy。

另乙個需要注意的問題是關於執行緒安全,在宣告block屬性時需要確認「在呼叫block時另乙個執行緒有沒有可能去修改block?」這個問題,如果確定不會有這種情況發生的話,那麼block屬性宣告可以用nonatomic。如果不肯定的話(通常情況是這樣的),那麼你首先需要宣告block屬性為atomic,也就是先保證變數的原子性(objective-c並沒有強制規定指標讀寫的原子性)。

但是,有了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抓取的變數一樣會被blockretain,所以必須用弱引用才可以解決迴圈引用問題,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)

;

建議132 考慮用類名作為屬性名

建議132 考慮用類名作為屬性名 一般來說,若果屬性對應乙個型別,應該直接用型別名命名屬性名。如下 class person class company 沒有必要為屬性名指定另外的名字,如 public company thecompany當然,除非我們的型別當中有多個company型別的屬性,這樣...

類A的物件作為類B的成員時,類A的建構函式如何呼叫

class a class b int main int argc,const char ar 執行結果 可以看出類a先於類b構造,這是符合構造類物件時的執行順序的。由於類a和類 都是空類,雖然類 包含了類 的物件,然而他們所占用的記憶體大小依舊都是 class a class b int main...

用BeanUtils框架操作類的屬性

首先匯入 commons logging.jar commons beanutils 1.8.0.jar 這兩個架包用beanutils框架操作類的屬性 test public void test1 throws exception,invocationtargetexception test pu...