美文网首页
【block第三篇】__block修饰符

【block第三篇】__block修饰符

作者: xxxxxxxxx_ios | 来源:发表于2018-12-28 11:57 被阅读4次

1.__block简介

__block可以用于解决block内部无法修改auto变量值的问题, __block不能修饰全局变量、静态变量(static),编译器会将__block变量(不管是基本数据类型还是对象类型)包装成一个对象。

  • 代码
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "YMPerson.h"
typedef void(^YMBlock)(void);

int main(int argc, char * argv[]) {
    @autoreleasepool {
        
        // 基本数据类型
        __block int a = 10;
        YMBlock block = ^{
            a = 20;
        };
        block();
        NSLog(@"a == %d",a);
        
        // 对象类型
        YMPerson *person = [[YMPerson alloc] init];
        person.age = 10;
        __block YMPerson *blockPerson = person;
        YMBlock block1 = ^{
            
            // 这不是修改person对象 是使用person对象 此步骤不使用__block修饰也可
            person.age = 20;
            
            // 修改person对象,必须用__block修饰
            blockPerson = [[YMPerson alloc] init];
            blockPerson.age = 100;
        };
        block1();
        NSLog(@"person.age == %d",person.age);
        NSLog(@"blockPerson.age == %d",blockPerson.age);
        
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}
  • 运行结果


    block修饰

2.__block修饰变量的内存管理

1.当block在栈上时,并不会对__block变量产生强引用。
2.当__block变量被copy到堆时,会调用__block变量内部的copy函数,copy函数内部会调用_Block_object_assign函数,_Block_object_assign函数会根据所指向对象的修饰(__strong、__weak、__unsafe_unretained)做出相应的操作,形成强引用(retain)或者弱引用(注意:这里仅限于ARC时会retain,MRC时不会retain)。
3. 如果__block变量从堆上移除,会调用__block变量内部的dispose函数,dispose函数内部会调用_Block_object_dispose函数,_Block_object_dispose函数会自动释放指向的对象(release)。

3.__block __weak同时修饰

block内部不会对对象进行强引用

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "YMPerson.h"
typedef void(^YMBlock)(void);

int main(int argc, char * argv[]) {
    @autoreleasepool {
        
       
        YMBlock block;
        {
            YMPerson *person = [[YMPerson alloc] init];
            person.age = 10;
            __block __weak YMPerson *blockPerson = person;
            block = ^{
                blockPerson.age = 100;
            };
        }
        block();
        NSLog(@"---");

        
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}
  • 运行结果


    __block __weak 同时修饰

相关文章

网友评论

      本文标题:【block第三篇】__block修饰符

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