關(guān)于weak解除block循環(huán)引用的疑問?

環(huán)境:ARC
命令:clang -rewrite-objc -fobjc-arc -stdlib=libc++ -mmacosx-version-min=10.7 -fobjc-runtime=macosx-10.7 -Wno-deprecated-declarations AnyThing.m

  • strong self
#import <Foundation/Foundation.h>
@interface AnyThing : NSObject
@end

#import "AnyThing.h"
@implementation AnyThing
- (void)someAct{
    void (^test)() = ^ {
        NSLog(@"%@",self);
    };
    test();
}
@end
// @implementation AnyThing


struct __AnyThing__someAct_block_impl_0 {
    struct __block_impl impl;
    struct __AnyThing__someAct_block_desc_0* Desc;
    AnyThing *const __strong self;//<<<不同
    __AnyThing__someAct_block_impl_0(void *fp, struct __AnyThing__someAct_block_desc_0 *desc, AnyThing *const __strong _self, int flags=0) : self(_self) {
        impl.isa = &_NSConcreteStackBlock;
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
    }
};

static void __AnyThing__someAct_block_func_0(struct __AnyThing__someAct_block_impl_0 *__cself) {
    AnyThing *const __strong self = __cself->self; // bound by copy
    
    NSLog((NSString *)&__NSConstantStringImpl__var_folders_qp_p2pj3jmj65n39jgl4wx9_l9w0000gn_T_AnyThing_51e757_mi_0,self);
}

static void __AnyThing__someAct_block_copy_0(struct __AnyThing__someAct_block_impl_0*dst, struct __AnyThing__someAct_block_impl_0*src) {
_Block_object_assign((void*)&dst->self, (void*)src->self, 3/*BLOCK_FIELD_IS_OBJECT*/);
}

static void __AnyThing__someAct_block_dispose_0(struct __AnyThing__someAct_block_impl_0*src) {
_Block_object_dispose((void*)src->self, 3/*BLOCK_FIELD_IS_OBJECT*/);
}

static struct __AnyThing__someAct_block_desc_0 {
    size_t reserved;
    size_t Block_size;
    void (*copy)(struct __AnyThing__someAct_block_impl_0*, struct __AnyThing__someAct_block_impl_0*);
    void (*dispose)(struct __AnyThing__someAct_block_impl_0*);
} __AnyThing__someAct_block_desc_0_DATA = { 0, sizeof(struct __AnyThing__someAct_block_impl_0), __AnyThing__someAct_block_copy_0, __AnyThing__someAct_block_dispose_0};

static void _I_AnyThing_someAct(AnyThing * self, SEL _cmd) {
 void (*test)() = ((void (*)())&__AnyThing__someAct_block_impl_0((void *)__AnyThing__someAct_block_func_0, &__AnyThing__someAct_block_desc_0_DATA, self, 570425344));
 ((void (*)(__block_impl *))((__block_impl *)test)->FuncPtr)((__block_impl *)test);
}

// @end
  • weak self
#import <Foundation/Foundation.h>
@interface AnyThing : NSObject
@end

#import "AnyThing.h"
@implementation AnyThing
- (void)someAct{
    __weak __typeof(&*self)weakSelf = self;
    void (^test)() = ^ {
        NSLog(@"%@",weakSelf);
    };
    test();
}
@end
// @implementation AnyThing


struct __AnyThing__someAct_block_impl_0 {
    struct __block_impl impl;
    struct __AnyThing__someAct_block_desc_0* Desc;
    __weak typeof (&*self) weakSelf;//<<<不同
    __AnyThing__someAct_block_impl_0(void *fp, struct __AnyThing__someAct_block_desc_0 *desc, __weak typeof (&*self) _weakSelf, int flags=0) : weakSelf(_weakSelf) {
        impl.isa = &_NSConcreteStackBlock;
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
    }
};

static void __AnyThing__someAct_block_func_0(struct __AnyThing__someAct_block_impl_0 *__cself) {
    __weak typeof (&*self) weakSelf = __cself->weakSelf; // bound by copy
    
    NSLog((NSString *)&__NSConstantStringImpl__var_folders_qp_p2pj3jmj65n39jgl4wx9_l9w0000gn_T_AnyThing_fda013_mi_0,weakSelf);
}

static void __AnyThing__someAct_block_copy_0(struct __AnyThing__someAct_block_impl_0*dst, struct __AnyThing__someAct_block_impl_0*src) {
_Block_object_assign((void*)&dst->weakSelf, (void*)src->weakSelf, 3/*BLOCK_FIELD_IS_OBJECT*/);
}

static void __AnyThing__someAct_block_dispose_0(struct __AnyThing__someAct_block_impl_0*src) {
_Block_object_dispose((void*)src->weakSelf, 3/*BLOCK_FIELD_IS_OBJECT*/);
}

static struct __AnyThing__someAct_block_desc_0 {
    size_t reserved;
    size_t Block_size;
    void (*copy)(struct __AnyThing__someAct_block_impl_0*, struct __AnyThing__someAct_block_impl_0*);
    void (*dispose)(struct __AnyThing__someAct_block_impl_0*);
} __AnyThing__someAct_block_desc_0_DATA = { 0, sizeof(struct __AnyThing__someAct_block_impl_0), __AnyThing__someAct_block_copy_0, __AnyThing__someAct_block_dispose_0};

static void _I_AnyThing_someAct(AnyThing * self, SEL _cmd) {
 __attribute__((objc_ownership(weak))) __typeof(&*self)weakSelf = self;
 void (*test)() = ((void (*)())&__AnyThing__someAct_block_impl_0((void *)__AnyThing__someAct_block_func_0, &__AnyThing__someAct_block_desc_0_DATA, weakSelf, 570425344));
 ((void (*)(__block_impl *))((__block_impl *)test)->FuncPtr)((__block_impl *)test);
}

// @end

根據(jù)上面的不同,知道:

strong
struct __AnyThing__someAct_block_impl_0對(duì)self保持強(qiáng)引用
weak
struct __AnyThing__someAct_block_impl_0對(duì)self保持弱引用

strong weak 對(duì)捕獲對(duì)象的拷貝,傳入flag一模一樣

static void __AnyThing__someAct_block_copy_0(struct __AnyThing__someAct_block_impl_0*dst, struct __AnyThing__someAct_block_impl_0*src) {
_Block_object_assign((void*)&dst->self, (void*)src->self, 3/*BLOCK_FIELD_IS_OBJECT*/);
}
static void __AnyThing__someAct_block_copy_0(struct __AnyThing__someAct_block_impl_0*dst, struct __AnyThing__someAct_block_impl_0*src) {
_Block_object_assign((void*)&dst->weakSelf, (void*)src->weakSelf, 3/*BLOCK_FIELD_IS_OBJECT*/);
}
void _Block_object_assign(void *destAddr, const void *object, const int flags) {
    //printf("_Block_object_assign(*%p, %p, %x)\n", destAddr, object, flags);
    ......
    else if ((flags & BLOCK_FIELD_IS_OBJECT) == BLOCK_FIELD_IS_OBJECT) {
        //printf("retaining object at %p\n", object);
        _Block_retain_object(object);//加引用計(jì)數(shù)?
        //printf("done retaining object at %p\n", object);
        _Block_assign((void *)object, destAddr);
    }
}

strong self 加引用計(jì)數(shù),可以理解!
weak self 加引用計(jì)數(shù),是不是有些矛盾?


不要奇怪,ARC環(huán)境有了更完善的內(nèi)存管理敌土,如果外部變量由__strong是掰、copy箕般、strong修飾時(shí)蛤迎,Block會(huì)把捕獲的變量用__strong來修飾進(jìn)而達(dá)到持有的目的.這里的_Block_retain_object只不過是一個(gè)空操作.
以下代碼見于BlocksRuntime/runtime.c

static void (*_Block_retain_object)(const void *ptr) = _Block_retain_object_default;
static void _Block_retain_object_default(const void *ptr __unused) {
}

分割線很好的隔開了疑問與回答,在此特別感謝解開我疑惑的啊哈呵同學(xué).

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市觅彰,隨后出現(xiàn)的幾起案子吩蔑,更是在濱河造成了極大的恐慌,老刑警劉巖填抬,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烛芬,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡飒责,警方通過查閱死者的電腦和手機(jī)赘娄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宏蛉,“玉大人遣臼,你說我怎么就攤上這事∈安ⅲ” “怎么了揍堰?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嗅义。 經(jīng)常有香客問我屏歹,道長(zhǎng),這世上最難降的妖魔是什么之碗? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任蝙眶,我火速辦了婚禮,結(jié)果婚禮上继控,老公的妹妹穿的比我還像新娘械馆。我一直安慰自己胖眷,他們只是感情好武通,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布霹崎。 她就那樣靜靜地躺著,像睡著了一般冶忱。 火紅的嫁衣襯著肌膚如雪尾菇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天囚枪,我揣著相機(jī)與錄音派诬,去河邊找鬼。 笑死链沼,一個(gè)胖子當(dāng)著我的面吹牛默赂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播括勺,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼缆八,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了疾捍?” 一聲冷哼從身側(cè)響起奈辰,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乱豆,沒想到半個(gè)月后奖恰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宛裕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年瑟啃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揩尸。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛹屿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出疲酌,到底是詐尸還是另有隱情蜡峰,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布朗恳,位于F島的核電站湿颅,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏粥诫。R本人自食惡果不足惜油航,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怀浆。 院中可真熱鬧谊囚,春花似錦怕享、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至奠伪,卻和暖如春跌帐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绊率。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工谨敛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滤否。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓脸狸,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親藐俺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子炊甲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容