block概念
block本质上是一个OC对象(结构体),它享有所有OC对象的待遇,只不过普通OC对象用来封装数据,而block用来封装函数以及函数的调用环境。所谓封装函数,是指block内部会把block的参数、返回值、执行体封装成一个函数,并且存储该函数的内存地址;所谓封装函数的调用环境,是指block内部会捕获变量,并且存储这些捕获的变量。
block分类
NSGlobalBlock 全局block
,位于内存全局区,未引用任何局部变量
void (^block)(void) = ^{
NSLog(@"Cooci");
};
NSLog(@"%@",block);
NSMallocBlock,堆区 block
, 引用局部变量的block,ARC
下 将block
赋值给strong
引用时。打印的block就是NSMallocBlock
int a = 10;
void (^block)(void) = ^{
NSLog(@"Cooci--%d",a);
};
NSLog(@"%@",block);
NSStackBlock,栈区Block
,ARC
下 不将block赋值给 strong引用时。打印的block就是NSStackBlock
int a = 10;
void (^__weak block)(void) = ^{
NSLog(@"Cooci - %d",a);
};
NSLog(@"%@",block);
##循环引用
如图所示,A与B之间相互持有,导致两者之间都无法释放
NSString *name = @"Dragon";
self.block = ^(void){
NSLog(@"%@",self.name);
};
self.block();
###解决方法
weak-stong-dance
强弱共舞- 如果block内部并未嵌套block,直接使用
__weak
修饰self即可
- 如果block内部并未嵌套block,直接使用
self.name = @"dragon";
__weak typeof(self) weakSelf = self;
self.block = ^(void){
NSLog(@"%@",weakSelf.name);
};
self.block();
- 如果block内部嵌套block,需要同时使用
__weak
和__strong
self.name = @"cooci";
__weak typeof(self) weakSelf = self;
self.block = ^(void){
__strong typeof(weakSelf) strongSelf = weakSelf;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@", strongSelf.name);
});
};
self.block();
- 中介者模式
手动
释放
__block ViewController *vc = self;
self.block = ^(void){
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@",vc.name);
vc = nil;//手动释放
});
};
self.block();
注:block必须调用
,这样临时变量vc
才能置空
,以保证self与block
的释放
2.自动
释放
typedef void(^KCBlock)(ViewController *);
@property(nonatomic, copy) KCBlock block;
self.block = ^(ViewController *vc){
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@",vc.name);
});
};
self.block(self);
注:将对象self
作为参数,提供给block内部使用,当self释放的时候对应的block也可以释放,就不会存在相互持有
的问题
NSProxy
虚拟类
OC
是单继承
机制,可以通过NSProxy
实现伪多继承
的方式
NSProxy 和 NSObject
是同级的一个类,也可以说是一个虚拟类,只是实现了NSObject的协议
NSProxy
其实是一个消息重定向封装
的一个抽象类,类似一个代理人,中间件,可以通过继承它
- (id)transformObjc:(NSObject *)objc{
_objc = objc;
return self;
}
+ (instancetype)proxyWithObjc:(id)objc{
return [[self alloc] transformObjc:objc];
}
//2.有了方法签名之后就会调用方法实现
- (void)forwardInvocation:(NSInvocation *)invocation