Block 到底是什么?
它就是里面存储了指向定义Block时的代码块的函数指针,以及Block 外部上下文变量信息的结构体。
1.循环引用
- weak strong dance
-(void)viewDidLoad{
[super viewDidLoad];
__weak typeof(self) weakSelf = self;
self.block = ^{
__strong typeof(self ) strongSelf = weakSelf;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2 * NSEC_PER_SEC)),dispatch_get_main_queue(),^{
NSLog(@"%@",strongSelf.name);
});
};
self.block();
}
- self -> block - >vc (nil) -> self
-(void)viewDidLoad{
[super viewDidLoad];
__block ViewController *vc = self;
self.block = ^{
__strong typeof(self ) strongSelf = weakSelf;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2 * NSEC_PER_SEC)),dispatch_get_main_queue(),^{
NSLog(@"%@",vc.name);
});
}
self.block();
};
-(void)viewDidLoad{
[super viewDidLoad];
self.block = ^(ViewController * vc){
__strong typeof(self ) strongSelf = weakSelf;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2 * NSEC_PER_SEC)),dispatch_get_main_queue(),^{
NSLog(@"%@",vc.name);
vc = nil;
});
}
self.block(self);
}
2. 例题
例1
三次打印均有值,因为Block内部对otherObject 进行了持有,它有引用计数为2,
当otherObject = nil 时,Block 内部仍然对其持用,它的引用计数为1
stuct block{
__strong NSObject * otherObject = 外部变量值;
function{
NSLog(........);
}
}
NSobject *otherObject = [NSObject alloc]init];
NSlog(otherObject %p & otherObject %p ,otherObject, &otherObject);
blk = ^{
NSlog(otherObject %p & otherObject %p ,otherObject, &otherObject);
}
blk();
otherObject = nil;
blk();
例2
block 没有对otherObject 进行持有,引用计数为1
所以当otherObject = nil 后,对象释放,引用计数为0,所以打印没值
stuct block{
__weak NSObject * otherObject = 外部变量值;
function{
__strong typeof(weakObject) strongObject = weakObject;
NSLog(........);
}
}
NSobject *otherObject = [NSObject alloc]init];
NSlog(otherObject %p & otherObject %p ,otherObject, &otherObject);
__weak typeof(otherObject) weakObject = otherObject;
blk = ^{
__strong typeof(weakObject) strongObject = weakObject;
NSlog(otherObject %p & otherObject %p , strongObject, & strongObject);
}
blk();
otherObject = nil;
blk();
例 3
Block 内部弱引用外部otherObject,但Block内部函数强引用,所以在内部执行休眠3秒后,依然能打印值,但otherObject = nil 后,休眠5秒,再执行block ,因为对象已经释放,所以没有打印。
stuct block{
__weak NSObject * otherObject = 外部变量值;
function{
__strong typeof(weakObject) strongObject = weakObject;
NSLog(........);
sleep(3);
NSLog(........);
}
}
NSobject *otherObject = [NSObject alloc]init];
__weak typeof(otherObject) weakObject = otherObject;
blk = ^{
__strong typeof(weakObject) strongObject = weakObject;
NSlog(otherObject %p & otherObject %p , strongObject, & strongObject);
sleep(3);
NSlog(otherObject %p & otherObject %p , strongObject, & strongObject);
}
blk();
otherObject = nil;
sleep(5);
blk();
例 4
Block 内部只对Self 进行了强持有,但成员变量并没有强持有,所以object = nil 后,对象释放,打印无内容。
stuct block{
typeOf(self ) *tmpSelf = self;
function{
NSLog(........);
}
}
//成员变量
object = [NSObject alloc]init];
NSlog(object %p &object %p , object, & object);
blk = ^{
NSlog(object %p &object %p , object, & object);
}
blk();
object = nil;
blk();
例5
__block char key = 0; //key 在栈区
objc_setAssociatedObjec(self, &key, @1, OBJC_ASSOCIATION_ASSIGN);
void(^block)(void) = ^(){
objc_setAssociatedObjec(self, &key, @2, OBJC_ASSOCIATION_ASSIGN);
} ///堆区
id m = objc_getAssociatedObjec(self, &key);
block();
id n = objc_getAssociatedObject(self,&key);
NSLog(@"m = %@, n = %@",m,n);