環(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é).