iOS Block

block 是objective-c对C做的扩展,使用block可以更好的简化objective-c编程,可以理解为匿名函数。
在objective-c中block是由结构体表示:

struct Block_layout {
    void *isa;
    int flags;
    int reserved;
    void (*invoke)(void *, ...);
    struct Block_descriptor *descriptor;
    /* Imported variables. */
};

struct Block_descriptor {
    unsigned long int reserved;
    unsigned long int size;
    void (*copy)(void *dst, void *src);
    void (*dispose)(void *);
};
image.png

block 使用全局变量,静态全局变量,自动变量,静态变量

NSInteger global_int = 1;//全局变量
static NSInteger static_global_int = 2; //静态全局变量

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSInteger m_int = 3;//自动变量
        static NSInteger static_int = 4;//静态变量
        
        void(^testBlock)(void)=^{
            //m_int ++; //在代码中自动变量会报错。
            static_int ++;
            global_int ++;
            static_global_int ++;
            NSLog(@"block 内部:m_int:%ld  static_int:%ld  global_int:%ld  static_global_int:%ld ",
                  (long)m_int, (long)static_int,(long)global_int, (long)static_global_int);
            
        };
        
        m_int ++;
        static_int ++;
        global_int ++;
        static_global_int ++;
        NSLog(@"block 外部:m_int:%ld  static_int:%ld  global_int:%ld  static_global_int:%ld ",
              (long)m_int, (long)static_int,(long)global_int, (long)static_global_int);
        
        testBlock();
        
    }
    return 0;
}

运行结果

block 外部:m_int:4  static_int:5  global_int:2  static_global_int:3 
block 内部:m_int:3  static_int:6  global_int:3  static_global_int:4 

可知:

1.在block中中不可直接使用自动变量
2.外面的自动变量有变化也不会影响block内部的自动变量
3.静态变量,全局变量,静态全局变量在前面有变化会影响block内部的变量

解释:

1.自动变量是以值传递的方式传到block中,所以不可以不能改变自动变量的值
2.全局变量和静态全局变量应为作用域为整个工程,存储在全局区,所以可以在block中改变
3.静态变量是传地址的方式到block中,所以在block中可以改变

总结:
在block中改变变量值有两种方式:
1.以传地址的方式进入block
2.改变存储方式(在变量前加__block,例如上面的自动变量,在前面加 __block就可以在block内部改变值)

参考:
1.https://www.jianshu.com/p/bcd494ba0e22
2.https://www.jianshu.com/p/ee9756f3d5f6

你可能感兴趣的:(iOS Block)