Block在开发中的使用非常常见,block本身属于代理模式,block在内存管理上一共有三种存储方式,也就是block有三种类型。
类 | 对象的存储区域 |
---|---|
_NSContreteStackBlcok | 栈 |
_NSContreteGlobalBlcok | 程序的数据区域(.data区) |
_NSContreteMallocBlcok | 堆 |
其实通俗一点就是,我们经常看到的系统block基本都是在函数栈上的,调用完就释放,但是使用过copy关键字的block就会到堆上去,需要手动内存管理。
在使用FMDB开发的过程中,常用事务操作的时候,经常调用这个方法
- (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block ;
在上面的方法中,发现BOOL变量竟然是加了*的,所以很好奇的点击去看了一下,因为BOOL类型的变量在blcok中改变值得话需要加上__block关键字,但是作者没有这样做,使用指针来解决这个问题。
- (void)beginTransaction:(BOOL)useDeferred withBlock:(void (^)(FMDatabase *db, BOOL *rollback))block {
FMDBRetain(self);
dispatch_sync(_queue, ^() {
BOOL shouldRollback = NO;
if (useDeferred) {
[[self database] beginDeferredTransaction];
}
else {
[[self database] beginTransaction];
}
//取指针的地址的值 调用block
block([self database], &shouldRollback);
if (shouldRollback) {
[[self database] rollback];
}
else {
[[self database] commit];
}
});
FMDBRelease(self);
}
我自己也写了一个Demo
//声明一个block
typedef void(^CustomBlock)(BOOL *status);
//使用
BOOL boolStatus = NO;
CustomBlock block = ^(BOOL *status){
*status = YES;
};
//取到指针的值调用block
block(&boolStatus);
if (boolStatus) {
NSLog(@"yes");
}else{
NSLog(@"no");
}
Debug log
欢迎讨论!