__attribute__ 高级运用

作者: 洲洲哥 | 来源:发表于2018-08-22 20:35 被阅读13次

    本文首发地址

    __attribute__((cleanup(...))),用于修饰一个变量(对象),在它的作用域结束时可以自动执行一个指定的方法

    例如:

    基本用法

    1:对于Class对象

    // 指定一个cleanup方法,注意入参是所修饰变量的地址,类型要一样
    // 对于指向objc对象的指针(id *),如果不强制声明__strong默认是__autoreleasing,造成类型不匹配
    
    // 加了个`unused`的attribute用来消除`unused variable`的warning
    
    
    static void ZZGCleanUp(__strong ZZG **zzg) {
        NSLog(@"%@",*zzg);
    }
    
    {
    // 调用
    __strong Sark *sark __attribute__((cleanup(ZZGCleanUp),unused)) = [ZZG new];
    }
    // 当运行到这个作用域结束时,自动调用ZZGCleanUp
    

    2:对于NSString对象

    
    static void stringCleanUp(__strong NSString **string) {
        NSLog(@"%@", *string);
    }
    
    
    {
        __strong NSString *string __attribute__((cleanup(stringCleanUp))) = @"ZZG";
    } // 当运行到这个作用域结束时,自动调用stringCleanUp
    

    高级用法

    1:既然__attribute__((cleanup(...)))可以用来修饰变量,block当然也是其中之一
    一块搞一个block

    // void(^block)(void)的指针是void(^*block)(void)
    
    static void blockCleanUp(__strong void(^*block)(void)) {
        (*block)();
    }
    
    
    于是在一个作用域里声明一个block:
    {
        __strong void(^block)(void) __attribute__((cleanup(blockCleanUp), unused)) = ^{
            NSLog(@"block.......");
        };
    } // 这里输出"block......."
    
    

    2:写一个实例如下

    2.1:创建一个AttributeLock

    .h中如下定义

    typedef void (^zzg_cleanupBlock_t)(void);
    static inline void zzg_executeCleanupBlock (__strong zzg_cleanupBlock_t *block) {
        (*block)();
    }
    
    // 该对象在代码段释放前调用的函数
    #define attributeExit\
          __strong void(^block)(void) __attribute__ ((cleanup(zzg_executeCleanupBlock),unused)) = ^
    
    #import <Foundation/Foundation.h>
    @interface AttributeLock : NSObject
    -(void)start;
    -(void)stop;
    @end
    

    .m如如下

    #import "AttributeLock.h"
    
    @implementation AttributeLock
    1. -(void)dealloc {
        NSLog(@"---dealloc");
        
    }
    -(void)start {
        NSLog(@">>>>>>>start");
    }
    -(void)stop {
        NSLog(@"<<<<<<stop");
    }
    @end
    

    2.2:调用如下

    AttributeLock * loc = [[AttributeLock alloc] init];
        [loc start];
        // *** 该方法可以放在任何位置
        attributeExit {
            NSLog(@"===========exit");
        };
        
        [loc stop];
    

    2.3:打印如下

    2018-08-22 20:16:18.524553+0800 POSPay[83808:9075309] >>>>>>>start
    2018-08-22 20:16:18.524708+0800 POSPay[83808:9075309] <<<<<<stop
    2018-08-22 20:16:18.524923+0800 POSPay[83808:9075309] ===========exit
    2018-08-22 20:16:18.525214+0800 POSPay[83808:9075309] ---dealloc
    

    可以看出在dealloc之前调用该方法

    总结ps:

    1* 作用域结束时可以自动执行一个指定的方法

    2* 指定一个cleanup方法,要注意传入的参数修饰变量的地址,并且类型要一样。并且对于指向Objc对象的指针(id *),如果不强制声明__strong 默认是__autoreleasing,造成类型不匹配

    3* 只有在作用域结束时会自动调用cleanup中的方法

    4* 如果一个作用域内有若干个cleanup的变量,他们的调用顺序是先入后出的栈式顺序。而且,cleanup是优先于这个对象的dealloc调用

    有些地方说的不到位,还请各位看官指正。。。

    • 如有问题可添加QQ群:234812704
    • 欢迎各位一块学习,提高逼格!
    • 也可以添加洲洲哥的微信公众号

    可以来微信公众号(洲洲哥)后台给我们留言。 快来扫码关注我们吧!

    公众号二维码

    相关文章

      网友评论

        本文标题:__attribute__ 高级运用

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