Runtime objc4-779.1 Runtime在实际开发中的应用之__attribute__

这是一个llvm的指令,很强大,官方文档中有很多说明,我们这里记录我们在开发中可能会遇到的场景和应用

指令格式

__attribute__(相关属性)

常见场景1 availability 对版本、平台等情况做说明

在某些时候我们需要对不同的版本和平台做特别处理,或者API支持,苹果也有很多这种场景,比如iOS10的系统通知API,UITableView中某些API的限定使用的API_DEPRECATED等宏定义的背后都是用__attribute__(availability...)实现的
eg:
在这里插入图片描述

我们如果遇到这种场景大可以使用API_XXXX等宏定义实现我们的需求,但是这里我们探究一下背后的__attribute__(availability...)

availability的参数如下

  • introduced:引进的版本
  • deprecated:废弃的版本,还能使用,并没有移除,而是提醒用户迁移到其他API
  • obsoleted:移除的版本,不能再使用
  • unavailable:那些平台不能用
  • message:额外提示信息,比如迁移到某某API

使用ios macosx来指定对应的平台

实际例子:
在这里插入图片描述

效果(实验环境XCode11.1(11A1027)) iOS 13.1:

在这里插入图片描述
系统中的NS_UNAVAILABLE就是使用的第二种方式实现的.

常见场景2 objc_subclassing_restricted 限定被修饰的类不能被其他类继承

在这里插入图片描述
在这里插入图片描述

常见场景3 cleanup 修饰一个变量,在它的作用域结束时可以自动执行一个指定的方法

在这里插入图片描述
注意:

  • 1,使用cleanup的时候约定调用的方法默认必须需要一个参数,这个参数就是被监听的对象本身
  • 2,调用方法用C语言,并且形参为指针的指针
  • 3,可以传递block
  • 4,执行顺序如下图所示
    在这里插入图片描述

常用场景4 objc_designated_initializer控制初始化方法必须被调用

在系统提供的宏定义中有这么一个

#define	NS_DESIGNATED_INITIALIZER	__attribute__((objc_designated_initializer))

被它修饰的初始化方法是强制要求被调用的,换句话说就是,如果你在本类中新写了其他的初始化方法,你也必须在你的方法中调用此方法,所以我们就可以利用这个修饰来写一个本类必须的初始化过程,然后提供给其他初始化方法使用,或者让其直接被调用.可以很好的控制本类对象在初始化过程的必要条件保证.

系统中最常见的应用就是NSObject中的init方法
在这里插入图片描述
注意事项

事项1: 如果本类有的初始化方法,那么它必须覆盖实现父类的objc_designated_initializer方法,否则会有如下警告

在这里插入图片描述在这里插入图片描述
我们按照警告提示复写了父类的init方法,却出现了另外的警告
在这里插入图片描述
大体解释就是说,因为你本类有一个objc_designated_initializer初始化方法,那么,你就必须用本类的初始化方法,而不能用父类的.

在这里插入图片描述
果然,将[super init]改成[self init]后不报警告了

对objc_designated_initializer使用总结就是

  • 1, 如果本类有objc_designated_initializer方法,那么必须重写父类的objc_designated_initializer方法
  • 2, 初始化方法如果被objc_designated_initializer修饰,那么在其中必须调用父类的objc_designated_initializer方法
  • 3, 如果本类有objc_designated_initializer初始化方法,那么其他的非objc_designated_initializer初始化方法必须调用该objc_designated_initializer方法,不能调用父类的.

常见场景5 unused消除对象未被使用警告

在这里插入图片描述

常见场景6 objc_requires_super限定方法在重写时必须先调用父类方法

我们在父类中用objc_requires_super修饰一个方法
在这里插入图片描述
在子类中重写此方法
在这里插入图片描述

我们发现就报了让我们调用父类方法的警告.
在这里插入图片描述
遵循提示,我们在重写时,调用父类方法,警告消失

常用场景6 objc_runtime_name控制类在运行时的名称

标记TestSon类的运行时名称为test_runtime_name
在这里插入图片描述
打印
在这里插入图片描述
在这里插入图片描述
安全加固中的代码混淆的背后其实就是这个指令,可以防止别人看到我们类真实的名字

总结一下

  • 1, __attribute__的功能很强大,很灵活,在实际开发中我们可以针对不同的应用场景使用不同的指令让编译器满足我们的需求,提高效率,安全
  • 2, __attribute__指令有很多,我们介绍的都是日常会用到的,很多没有介绍道的,可以查看官方文档,则需而用.
发布了145 篇原创文章 · 获赞 36 · 访问量 41万+

猜你喜欢

转载自blog.csdn.net/wxs0124/article/details/104801074