美文网首页iOS Developer
iOS中一些__attribute__运用

iOS中一些__attribute__运用

作者: 北京小库里 | 来源:发表于2016-08-30 21:44 被阅读665次

    Clang Attributes是Clang提供的一种源码注解,方便开发者向编译器表达某种要求,参与控制如Static Analyzer、Name Mangling、Code Generation等过程,一般以attribute(xxx)的形式出现在代码中;为方便使用,一些常用属性也被Cocoa定义成宏,比如在系统头文件中经常出现的NS_CLASS_AVAILABLE_IOS(9_0)就是attribute(availability(...))这个属性的简单写法。

    ※unavailable
    #define UNAVAILABLE_ATTRIBUTE __attribute__((unavailable))

    可以加在方法声明的后面,告诉编译器该方法不可用

    Swift中

    @available(*, unavailable)
    
    func foo() {}
    
    @available(iOS, unavailable, message="you can't call this")
    
    func foo2() {}
    

    ※availability

    #define NS_DEPRECATED_IOS(_iosIntro,_iosDep,...) CF_DEPRECATED_IOS(_iosIntro,_iosDep,__VA_ARGS__)

    展开看

    #define CF_DEPRECATED_IOS(_iosIntro, _iosDep, ...) __attribute__((availability(ios,introduced=_iosIntro,deprecated=_iosDep,message="" __VA_ARGS__)))

    再展开看

    __attribute__((availability(ios,introduced=2_0,deprecated=7_0,message=""__VA_ARGS__)))

    iOS即是iOS平台

    introduced从哪个版本开始使用

    deprecated从哪个版本开始弃用

    message警告的信息

    其实还可以再加一个参数例子:

    void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7)));

    obsoleted完全禁止使用的版本

    NS_AVAILABLE_IOS(7_0) iOS7.0或之后才能使用

    NS_DEPRECATED_IOS(2_0,6_0) iOS2.0开始使用6.0废弃

    Swift中:

    @available(iOS 6.0, *)
    
    public var minimumScaleFactor: CGFloat
    
    @available(OSX, introduced=10.4, deprecated=10.6, obsoleted=10.10)
    
    @available(iOS, introduced=5.0, deprecated=7.0)
    
    func foo3() {}
    

    ※objc_subclassing_restricted

    一句话就是使用这个属性可以定义一个不可被继承的类

    __attribute__((objc_subclassing_restricted))
    
    @interface Eunuch : NSObject
    
    @end
    
    @interface Child : Eunuch//如果继承它会报错
    
    @end
    

    在Swift中对原来的很多attribute的支持现在还缺失中,为了达到类似的目的,我们可以使用一个final关键词


    final.png

    ※objc_requires_super

    使用这个属性标志子类继承这个方法时需要调用super,否则给出编译警告,来让父类中有一些关键代码是在被继承重写后必须执行

    #define NS_REQUIRES_SUPER __attribute__((objc_requires_super))

    super.png

    在Switf中也还是可以用final的方法来达到这个目的


    fatalError.png

    Swift equivalent to __attribute((objc_requires_super))?(stackoverflow)

    关于Swift中的final的详细讲解

    ※overloadable

    用于C函数,可以定义若干个相同函数名,但参数不同的方法,调用时编译器会自动根据参数选择函数去调用

    __attribute__((overloadable))
    
    void logAnything(id obj) {
    
    NSLog(@"%@", obj);
    
    }
    
    __attribute__((overloadable)) void logAnything(int number) {
    
    NSLog(@"%@", @(number));
    
    }
    
    __attribute__((overloadable)) void logAnything(CGRect rect) {
    
    NSLog(@"%@", NSStringFromCGRect(rect));
    
    }
    
    // Tests
    
    logAnything(@[@"1", @"2"]);
    
    logAnything(233);
    
    logAnything(CGRectMake(1, 2, 3, 4));
    

    有兴趣的可以写一个自定义的Log免去用NSLog要写@""等格式的麻烦

    ※cleanup

    __attribute__((cleanup(...))),用于修饰一个变量,在它的作用域结束时可以自动执行一个指定的方法,个人感觉这个真的很方便

    cleanUp.png

    一个对象可以这样用,那么block实际也是一个对象,这样就可以写一个宏,实际上就是ReactiveCocoa中神奇的@onExit

    #define onExit\
    
    __strong void(^block)(void) __attribute__((cleanup(blockCleanUp), unused)) = ^
    

    有时候我们需要用到锁这个东西,或者一些CoreFoundation的对象有时候最后需要释放,用这个宏就很方便了


    cleanUp2.png

    为了好看用这个宏的时候加个@就加个释放池就可以了


    cleanUp3.png

    sunnyxx这篇博客讲的很清楚

    Swift中:可以用defer


    defer.png

    还有一些format, const, noreturn, aligned , packed, objc_boxable, constructor / destructor, enable_if, objc_runtime_name可以看这两篇文章:

    神奇的attribute

    Clang Attributes黑魔法小记

    相关文章

      网友评论

        本文标题:iOS中一些__attribute__运用

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