环境: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
根据上面的不同
,知道:
strong
struct __AnyThing__someAct_block_impl_0对self保持强引用
weak
struct __AnyThing__someAct_block_impl_0对self保持弱引用
但
strong weak 对捕获对象的拷贝,传入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);//加引用计数?
//printf("done retaining object at %p\n", object);
_Block_assign((void *)object, destAddr);
}
}
strong self 加引用计数,可以理解!
weak self 加引用计数,是不是有些矛盾?
不要奇怪,ARC环境有了更完善的内存管理,如果外部变量由__strong
、copy
、strong
修饰时,Block会把捕获的变量用__strong
来修饰进而达到持有的目的.这里的_Block_retain_object
只不过是一个空操作.
以下代码见于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) {
}
分割线很好的隔开了疑问与回答,在此特别感谢解开我疑惑的啊哈呵同学.