1.block的分類
常見的三種block
-
(void
)viewdidload
;block()
;nslog
(@"%@"
,block);}
//列印結果
//block探析[2300:140310] 我是全域性block
//block探析[2300:140310] <__nsglobalblock__: 0x10d14e038>
-
(void
)viewdidload
;block()
;nslog
(@"%@"
,block);}
//列印結果:
//block探析[2416:146513] 我是全域性block---10
//block探析[2416:146513] <__nsmallocblock__: 0x600003db08d0>
-
(void
)viewdidload );
}//列印結果:
//block探析[2460:149166] <__nsglobalblock__: 0x109b7b038>
2.block捕獲外部變數
1.無__block修飾的區域性變數
#include
intmain()
;block()
;return0;
}//clang生成.cpp檔案
//下面是cpp檔案中main函式的實現**
intmain()
//這裡將我們block**塊裡面的**給了函式__main_block_func_0
//__main_block_impl_0:建構函式,返回值為乙個block!
//block的本質:結構體
struct __main_block_impl_0
}; */
void
(*block)
(void)=
((void(*
)())
&__main_block_impl_0((
void
*)__main_block_func_0,
&__main_block_desc_0_data, a));
/** //block結構體中的impl結構
struct __block_impl ;
//去掉強轉的**,這裡不就是block的呼叫:
block->funcptr(block);
*/((
void(*
)(__block_impl *))
((__block_impl *
)block)
->funcptr)
((__block_impl *
)block)
;return0;
}
2.__block修飾的區域性變數#include
intmain()
;block()
;return0;
}//clang生成.cpp檔案
//下面是cpp檔案中main函式的實現**
intmain()
; */
__attribute__((
__blocks__
(byref)
)) __block_byref_a_0 a =;//
/** 這裡block初始化的時候,傳進來的是__block_byref_a_0結構體型別的指標a;
struct __main_block_impl_0
};*/
void
(*block)
(void)=
((void(*
)())
&__main_block_impl_0((
void
*)__main_block_func_0,
&__main_block_desc_0_data,
(__block_byref_a_0 *
)&a,
570425344))
;//呼叫
/** static void __main_block_func_0(struct __main_block_impl_0 *__cself)
*/((
void(*
)(__block_impl *))
((__block_impl *
)block)
->funcptr)
((__block_impl *
)block)
;return0;
}
3.block迴圈引用-
(void
)viewdidload
;self
.block()
;}//這樣一段**,不用說,都知道會發生迴圈應用
//這是因為self->block->self形成了乙個閉環,並且都是強持有!
//所以這裡vc和block都無法釋放
//也就是說,只要打破這個迴圈,不會迴圈應用了!
//我們平時最多的使用是
//定義乙個弱引用weakself,指標指向self,因為是weak修飾,所以不對引用計數做任何操作
//__weak typeof(self) weakself = self;只需將self.name改為weakself.name就可打破迴圈
//這裡使用了中介者設計模式
//weakself(弱引用表)->self->block->weakself
//看需求及邏輯需要,只有這一句**有可能會有問題,
//比如把上面**改為:-(
void
)viewdidload );
};self
.block()
;}-(
void
)dealloc
//列印結果就是:
//block探析[3895:288440] 釋放了
//block探析[3895:288440] 我是---(null)
//列印的時候,vc已經釋放,屬性name肯定也被釋放了
//如果遇到這種情況,我們還需要做一步操作:
//__strong typeof(weakself) strongself = weakself;
改為strongself.name
//strongself臨時變數出了作用域會被釋放
//strongself->weakself(弱引用表)->self->block->weakself->strongself
//延遲釋放vc
//block探析[3922:291133] 我是---ios
//block探析[3922:291133] 釋放了
iOS 底層原理之 Block
block 本質上也是乙個 oc 物件,它內部也有個 isa 指標 block 是封裝了函式呼叫以及函式呼叫環境的 oc 物件 block 的底層結構如下圖所示 原始碼解析 struct gsblock load block impl 0 block impl struct block impl g...
iOS知識原理篇
weak策略表明該屬性定義了一種 非擁有關係 nonowning relationship 為這種屬性設定新值時,設定方法既不保留新值,也不釋放舊值。此特質同assign類似 然而在屬性所指的物件遭到摧毀時,屬性值也會清空 nil out runtime對註冊的類,會進行布局,會將 weak 物件放...
block的底層實現原理
block就是指向結構體的指標,編譯器會將block的內部 生成對應的函式,利用這個指標就可以呼叫這個函式.普通的區域性變數是值傳遞,用 block static 或者是全域性變數就是位址傳遞 block的記憶體預設是存放在棧裡面的,他不會對所引用的物件進行操作 如果對block做一次copy操作b...