美文网首页
iOS开发 Block

iOS开发 Block

作者: 喜剧收尾_XWX | 来源:发表于2021-01-11 00:21 被阅读0次

一、block分类

block是一中特殊的oc对象,主要分为以下3类

  • __NSGlobalBlock :没有访问外部auto自动变量,如果访问了全局静态变量static_global、局部静态变量static或者全局变量也是这种类型。且能改变全局变量的值。
static NSString *indexString = @"xingweixin";
extern NSString *myExternString;
extern NSString *myExternString2;

 self.block = ^{
        //全局变量
        myExternString2 = @"fengmengyue";
        NSLog(@"_____%@",myExternString2);
        NSLog(@"_____%@",indexString);
        
    };
    self.block();
    NSLog(@"%@",[self.block class]);   //__NSGlobalBlock

  • __NSStackBlock

(1)在MRC下访问了外部auto变量,则属于栈区block

int index = 15;
    void(^TestVCBlock)(void) = ^{
        NSLog(@"----%d",index);
    };
    TestVCBlock();
    NSLog(@"%@",[TestVCBlock class]);  //__NSStackBlock

(2) 在ARC下访问了外部变量,但没有强引用指向这个block

  int index = 15;
    NSLog(@"%@",[^{
        NSLog(@"----%d",index);
    } class]);
  • __NSMallocBlock

(1)在MRC下,用copy修饰__NSStackBlock后则为__NSMallocBlock

 void(^TestVCBlock)(void) = [^{
        NSLog(@"----%d",index);
    } copy];
    TestVCBlock();
    NSLog(@"%@",[TestVCBlock class]);

(2)在ARC下,ARC环境下只要访问了外部auto变量而且有强引用指向该block(或者作为函数返回值)就会自动将__NSStackBlock类型copy到堆上

 void(^TestVCBlock)(void) = ^{
        NSLog(@"----%d",index);
    } ;
    TestVCBlock();
    NSLog(@"%@",[TestVCBlock class]);

二、block特性

1.捕获自动变量

(1) 自动变量是什么时候被block捕获进去的?为什么值不能修改?

  • block捕获自动变量是捕获block体中用到的局部变量,用不到的不去捕获
  • 自动变量val虽然被捕获进来了,但是是用 __cself->val来访问的。Block仅仅捕获了val的值,并没有捕获val的内存地址。所以在__main_block_func_0这个函数中即使我们重写这个自动变量val的值,依旧没法去改变Block外面自动变量val的值。

(2) 全局变量和静态全局变量值在block为什么能更改,局部静态变量的值为什么能更改?

  • 全局变量global_i和静态全局变量static_global_j的值增加,以及它们被Block捕获进去,这一点很好理解,因为是全局的,作用域很广,所以Block捕获了它们进去之后,在Block里面进行++操作,Block结束之后,它们的值依旧可以得以保存下来。
  • 静态变量传递给Block是内存地址值,所以能在Block里面直接改变值。

(3)如何修改自动变量中的值

  • 传递内存地址到Block中,改变变量的值。
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
  NSMutableString * str = [[NSMutableString alloc]initWithString:@"Hello,"];
    
        void (^myBlock)(void) = ^{
            [str appendString:@"World!"];
            NSLog(@"Block中 str = %@",str);
        };
    
    NSLog(@"Block外 str = %@",str);
    
    myBlock();
    
    return 0;
}
  • 使用__block修饰局部变量

https://www.jianshu.com/p/ee9756f3d5f6

相关文章

网友评论

      本文标题:iOS开发 Block

      本文链接:https://www.haomeiwen.com/subject/iiplaktx.html