Block 到底是什么?
它就是里面存儲(chǔ)了指向定義Block時(shí)的代碼塊的函數(shù)指針,以及Block 外部上下文變量信息的結(jié)構(gòu)體。
1.循環(huán)引用
- 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
三次打印均有值,因?yàn)锽lock內(nèi)部對(duì)otherObject 進(jìn)行了持有,它有引用計(jì)數(shù)為2,
當(dāng)otherObject = nil 時(shí),Block 內(nèi)部仍然對(duì)其持用,它的引用計(jì)數(shù)為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 沒(méi)有對(duì)otherObject 進(jìn)行持有,引用計(jì)數(shù)為1
所以當(dāng)otherObject = nil 后,對(duì)象釋放,引用計(jì)數(shù)為0,所以打印沒(méi)值
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 內(nèi)部弱引用外部otherObject,但Block內(nèi)部函數(shù)強(qiáng)引用,所以在內(nèi)部執(zhí)行休眠3秒后,依然能打印值,但otherObject = nil 后,休眠5秒,再執(zhí)行block ,因?yàn)閷?duì)象已經(jīng)釋放,所以沒(méi)有打印。
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 內(nèi)部只對(duì)Self 進(jìn)行了強(qiáng)持有,但成員變量并沒(méi)有強(qiáng)持有,所以object = nil 后,對(duì)象釋放,打印無(wú)內(nèi)容。
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 在棧區(qū)
objc_setAssociatedObjec(self, &key, @1, OBJC_ASSOCIATION_ASSIGN);
void(^block)(void) = ^(){
objc_setAssociatedObjec(self, &key, @2, OBJC_ASSOCIATION_ASSIGN);
} ///堆區(qū)
id m = objc_getAssociatedObjec(self, &key);
block();
id n = objc_getAssociatedObject(self,&key);
NSLog(@"m = %@, n = %@",m,n);