Block的巧用

2016-11-23  本文已影响21人  迷了jiang

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


屏幕快照 2016-11-23 下午4.10.10.png

欢迎讨论!

上一篇下一篇

猜你喜欢

热点阅读