Block迴圈引用之weak strong

2021-08-28 08:16:55 字數 2251 閱讀 8229

在arc環境下,我們會使用_weak修飾符來修飾乙個變數防止其在block中被迴圈引用,特殊情況下還會在block中使用_strong修飾符來修飾這個變數如下

__weak __typeof(self)weakself = self;

afnetworkreachabilitystatusblock callback = ^(afnetworkreachabilitystatus status)

};

這是因為在block中呼叫self會引起迴圈引用,同時在block中需要對weakself進行strong操作,保證self不會被釋放,當block執行完會自動釋放該strongself。但實際上strong是為了防止野指標,而block裡大部分是用weakself訪問self的屬性,而不是區域性變數,我們也不可能主動釋放self,這樣看來就沒有strong的必要了當然不排除有特殊情況。

除開上面這種一般寫法,我們看看yykit中是怎麼使用weak&strong:

#ifndef weakify

#if debug

#if __has_feature(objc_arc)

#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;

#else

#define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;

#endif

#else

#if __has_feature(objc_arc)

#define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;

#else

#define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;

#endif

#endif

#endif

#ifndef strongify

#if debug

#if __has_feature(objc_arc)

#define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;

#else

#define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;

#endif

#else

#if __has_feature(objc_arc)

#define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;

#else

#define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;

#endif

#endif

#endif

/** example:

@weakify(self)

[self dosomething^];

*/

還有來自libextobjc的這種寫法:

#define weakify(...) \\

autoreleasepool {} \\

metamacro_foreach_cxt(rac_weakify_,, __weak, __va_args__)

#define strongify(...) \\

try {} @finally {} \\

_pragma("clang diagnostic push") \\

_pragma("clang diagnostic ignored \\"-wshadow\\"") \\

metamacro_foreach(rac_strongify_,, __va_args__) \\

_pragma("clang diagnostic pop")

其中細節可以參考這篇文章

block 迴圈引用

結論 block作為成員變數,內部引用self的成員變數,必須使用self 弱引用 block作為區域性變數,無論怎樣寫,都不會對self造成強引用 block為變數 1 block為成員變數 typedef nsstring blockcc void inte ce twoviewcontroll...

block迴圈引用

底層原始碼 typedef void ghblock void struct main block impl 0 static void main block func 0 struct main block impl 0 cself static void main block copy 0 st...

BLOCK迴圈引用

何時block才會迴圈引用 為什麼block會迴圈引用 我們很多行為會導致block的copy,而當block被copy時,會對block中用到的物件產生強引用 arc下 或者引用計數加一 mrc下 如下 property nonatomic,readwrite,copy completionblo...