IOS开发之Block(二)

IOS开发之Block(二)

前言

我目前在XX大厂实习,正在学习iOS开发,在此分享我的学习心得和一些实践经验。如果文中有任何不准确之处,欢迎指正。

正文

block有3种类型,可以调用class方法或者isa指针查看具体的类型,最终都继承NSBlock类型

NSGlobalBlock_ (NSConcreateGlobalBlock) 没有访问auto变量 程序的数据区域 copy:什么也不做
NSStackBlock
(NSConcreateStackBlock) 访问了auto变量 栈 copy:从栈复制到堆
NSMallocBlock
(_NSConcreteMallocBlock) __NSStackBlock__调用了copy copy:引用计数增加

来一张图片:
在这里插入图片描述

由于后面用到ARC/MRC环境,在Xcode设置:
在这里插入图片描述

#import <Foundation/Foundation.h>

void (^block123)(void);

void test(){
    int age = 100;
    block123 = ^{
        NSLog(@"block  %d ",age);
    };
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        // Global:没有访问auto变量   放在数据段
        void (^block)(void) = ^{
            NSLog(@"Hello world");
        };
        NSLog(@"%@",[block class]);   // __NSGlobalBlock__
        
        
        // stack:访问了auto变量
        int age = 10;
        void (^block1)(void) = ^{
            NSLog(@"Hello world - %d",age);
        };
        NSLog(@"%@",[block1 class]);    // ARC:__NSMallocBlock__
        
        int weight = 10;
        void (^block2)(void) = [^{
            NSLog(@"Hello world - %d",weight);
        } copy];	// 会在堆上创建内存存放和栈上相同的值
        NSLog(@"%@",[block2 class]);
        
        test();
        block123();
        
    }
    return 0;
}

输出:

上面都是MRC环境下
输出:
__NSGlobalBlock__
__NSStackBlock__
__NSMallocBlock__
block  -1074793912  

在这里输出" block -1074793912 "因为在MRC环境下离开其作用域导致的

ARC环境下,编译器会根据情况自动将栈上的block复制到堆上,以下情况

1、block作为函数返回值时

代码:

#import <Foundation/Foundation.h>

typedef void (^Block)(void);

Block myBlock(){
    // ARC   release也不需要我们调用
    return ^{
        NSLog(@"hello world");
    };;
}

Block myBlock2(){
    int age = 10;
    return ^{
        NSLog(@"hello world %d",age);
    };;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Block block1 = myBlock();
        block1();
        NSLog(@"%@",[block1 class]);  // __NSGlobalBlock__ 进行copy什么也不做
        
        Block block2 = myBlock2();
        block2();
        NSLog(@"%@",[block2 class]);  // __NSMallocBlock__
    }
    return 0;
}

2、将block赋值给__strong指针时

#import <Foundation/Foundation.h>

typedef void (^Block)(void);

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int age = 10;
        Block block = ^{
            NSLog(@"hello world %d",age);
        };
        NSLog(@"%@",[block class]);   // ARC: __NSMallocBlock__    MRC: __NSStackBlock__
        
        
        NSLog(@"%@",[^{         // __NSStackBlock__  没有强指针指向
            NSLog(@"hello world %d",age);
        } class]);
        
        NSLog(@"%@",[^{         // __NSGlobalBlock__
            NSLog(@"hello world %d");
        } class]);
    }
    return 0;
}

3、block作为Cocoa API中方法名含有usingBlock的方法参数时

#import <Foundation/Foundation.h>

// 像这种
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSArray* array = @[];
        
        [array enumerateObjectsUsingBlock:<#^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop)block#>]
    }
    return 0;
}

4、block作为GCD API的方法参数时

#import <Foundation/Foundation.h>


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            <#code to be executed once#>
        });
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            <#code to be executed after a specified delay#>
        });
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值