Block种类

木木木大约 3 分钟iOSBlock

Block种类

在 Objective-C 中,Block 是一种带有自动捕获变量的匿名函数。Block 可以在定义时捕获其外部作用域中的变量,并将这些变量保存在 Block 结构体中。当调用 Block 时,它会从结构体中获取这些变量,并执行函数体中的代码。Block 的定义形式如下:

^return_type (arguments) {
    // code
}

在 Block 的定义中,^ 符号表示它是一个 Block,return_type 表示 Block 的返回类型,arguments 表示 Block 的参数列表,code 表示 Block 的函数体。

NSStackBlock

NSStackBlock 是一种将 Block 对象分配在栈上的 Block。特点是在定义的作用域内有效,一旦作用域结束,Block 对象就会被销毁。

下面是一个使用 NSStackBlock 的示例:

void test() {
    int num = 100;
    void(^myBlock)(void) = ^{
        NSLog(@"num=%d", num);
    };
    myBlock();
}

定义了一个名为 myBlock 的 NSStackBlock,并在其中捕获了变量 num。当我们调用 myBlock 时,它会输出变量 num 的值,即 100。

需要注意的是,由于 NSStackBlock 是在栈上分配的,所以它的生命周期与作用域密切相关。一旦作用域结束,NSStackBlock 对象就会被销毁,而且如果我们在作用域结束后继续调用这个 Block,就会导致程序崩溃。

NSMallocBlock

NSMallocBlock 是一种将 Block 对象分配在堆上的 Block。特点是在定义的作用域外仍然有效,可以在其他作用域中使用,并且不会被随意销毁。

下面是一个使用 NSMallocBlock 的示例:

typedef void(^MyBlock)(void);

MyBlock getBlock() {
    int num = 100;
    MyBlock block = ^{
        NSLog(@"num=%d", num);
    };
    return block;
}

void test() {
    MyBlock myBlock = getBlock();
    myBlock();
}

定义了一个名为 myBlock 的 NSMallocBlock,并将它作为函数的返回值返回。在 test 函数中获取了这个 Block,并调用了它需要注意的是,由于 NSMallocBlock 是在堆上分配的,所以它的生命周期不会受限于作用域。也就是说,如果在其他作用域中调用这个 Block,它依然有效。

此外,由于 NSMallocBlock 是在堆上分配的,所以需要手动管理内存。当不再需要使用这个 Block 时,需要调用 Block_release 函数来释放它所占用的内存。

NSGlobalBlock

NSGlobalBlock 是一种不需要捕获外部变量的 Block,特点是在程序运行期间一直存在,不会被销毁。NSGlobalBlock 可以被多个线程同时调用,并且不需要考虑线程安全的问题。

下面是一个使用 NSGlobalBlock 的示例:

void test() {
    void(^myBlock)(void) = ^{
        NSLog(@"Hello, world!");
    };
    myBlock = [myBlock copy];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        myBlock();
    });
}

定义了一个名为 myBlock 的 NSGlobalBlock,并在异步线程中调用它。需要注意的是,由于 NSGlobalBlock 是全局的,所以不需要考虑它的生命周期,也不需要手动释放内存。

##总结 NSStackBlock、NSMallocBlock 和 NSGlobalBlock 是 Block 的三种不同类型,它们分别在栈上、堆上和全局区分配 Block 对象。NSStackBlock 的生命周期受限于作用域,NSMallocBlock 可以在作用域外继续使用,需要手动释放内存,而 NSGlobalBlock 是全局的,不需要考虑生命周期和内存管理的问题。

上次编辑于:
贡献者: perhapsdone