前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >浅谈 __attribute__

浅谈 __attribute__

作者头像
s_在路上
发布于 2019-03-08 03:02:09
发布于 2019-03-08 03:02:09
5.9K00
代码可运行
举报
文章被收录于专栏:iOS 开发杂谈iOS 开发杂谈
运行总次数:0
代码可运行

__attribute__ 是一个编译器指令,其实是 GNU C 的一种机制,本质是一个编译器的指令,在声明的时候可以提供一些属性,在编译阶段起作用,来做多样化的错误检查和高级优化。用于在 CC++Objective-C 中修饰变量、函数、参数、方法、类等。

合理使用 __attribute__ 有什么好处?

  • 给编译器提供上下文,帮助编译器做优化,合理使用可以收到显著的优化效果。
  • 编译器会根据 __attribute__ 产生一些编译警告,使代码更规范。
  • 给代码阅读者提供必要的注解,助其理解代码意图。

总之,__attribute__ 起到了给编译器提供上下文的作用,如果错误的使用 __attribute__ 指令,因为给编译器提供了错误的上下文,由此引起的错误通常很难被发现。

deprecated

适用于方法、属性。告诉编译器已经过时,如果使用了,会报过时警告

常用写法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 可以自定义描述信息
__attribute__((deprecated("已过期!")))
// 系统的宏定义
DEPRECATED_ATTRIBUTE 

使用场景:

在组件化、SDK 的时候,因为某个需求,我们升级了 API,但是需要兼容老的版本,并且希望使用者调用最新的 API

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 标记这个属性已过期
@property (nonatomic, copy) NSString *name __attribute__((deprecated("属性已过期")));

// 标记方法已过期
- (void)testOld __attribute__((deprecated("方法已过期, 请使用 test2"))) {  

}

- (void)testNew {

}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    // 编译器警告,'testOld' is deprecated: 已过期, 请使用 testNew
    [self testOld];

    // 编译器警告,提示 "'name' 已过期..."
    NSLog(@"%@", self.name);
}

unavailable

适用于方法、属性。告诉编译器不可用。如果使用了,就会编译失败,提示错误信息

常用写法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 可以自定义描述信息
__attribute__((unavailable("已经废弃,请使用 xxxx")))
// 系统宏定义
NS_UNAVAILABLE;
UNAVAILABLE_ATTRIBUTE;

使用场景:

自定义了 Class 的初始化方法,不希望外界使用 init 初始化,并且给出正确的提示。 比希望继续使用某个属性,并且给出正确的提示。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@interface ViewController : UIViewController

@property (nonatomic, copy) NSString *name __attribute__((unavailable("这个属性已经废弃")));

#pragma mark - 初始化
- (instancetype)init __attribute__((unavailable("这个方法已经废弃,请使用 initWithName:")));

- (instancetype)initWithName:(NSString *)Name;
@end

- (void) test {
    // 编译不通过,提示 "'init' 已经废弃了..."
    ViewController *vc = [[ViewController alloc] init];

    // 编译不通过,提示 "'name' 已经废弃了..."
    NSLog(@"%@", vc.name);
}

objc_subclassing_restricted

适用于 Class。告诉编译器我不能有子类,类似 final 关键字

常用写法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
__attribute__((objc_subclassing_restricted))

使用场景:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#import <Foundation/Foundation.h>

__attribute__((objc_subclassing_restricted))
@interface ClangTest : NSObject
@end

#import "ClangTest.h"

// 这里编译出错,提示“Cannot subclass a class that was declared with the 'objc_subclassing_restricted' attribute”
@interface ClangSonTest : ClangTest
@end

objc_requires_super

适用于方法。告诉编译器子类重写这个方法的时候,必须调用[Super xxx]

常用写法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 通用写法
__attribute__((objc_requires_super))

// 系统宏定义,其实和上面是一样的
NS_REQUIRES_SUPER

使用场景:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#import <Foundation/Foundation.h>

@interface ClangTest : NSObject

- (void)instanceMethod1 __attribute__((objc_requires_super));
@end


#import "ClangTest.h"

@interface ClangSonTest : KDClangTest
@end
@implementation KDClangSonTest

- (void)instanceMethod1 {
    NSLog(@"I am son");
    // 这里编译器会出现警告: Method possibly missing a [super instanceMethod1] call
}

constructor 与 destructor

使用 constructor 属性修饰的函数能在 main() 函数之前执行,而使用 destructor 属性修饰的函数,在 main() 函数结束或 exit() 函数调用后执行。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// main之前调用
__attribute__((constructor))

使用场景:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
__attribute__((constructor)) void before_main() {
    printf("app before main\n");
}

__attribute__((destructor)) void after_main() {
    printf("app after main\n");
}

int main(int argc, char * argv[]) {
    printf("excute main\n");
    return 0;
}

注意: 因为 load 是在 class 被加载的时候,就执行了,所以早于 constructor。 所以顺序应该是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
load -> attribute((constructor)) -> main -> attribute((destructor)) -> initialize

参考链接

https://nshipster.cn/attribute/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.02.25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
iOS_ __attribute__
__attribute__ 编译器属性机制,用于向编译器描述特殊得标识、检查或优化。 语法关键字是__attribute__紧跟2套圆括号,括号内是一个以逗号分隔的属性列表。 __attribute__指令被放在类前、函数/变量声明后面。
mikimo
2023/10/18
2830
颤抖吧!都在我的魔法下颤抖吧!--------我是 iOS 黑魔法师!
对于子类 B重写父类 A方法 method2在 iOS6.0之后才可以用是错误的,因为父类方法是可以在 iOS5.0就可以用的。
君赏
2018/09/07
7810
__attribute__机制介绍
__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)
阳光岛主
2019/02/19
3K0
iOS @property探究(二): 深入理解你要知道的@property都在这里
你要知道的@property都在这里 转载请注明出处 https://cloud.tencent.com/developer/user/1605429 上一篇文章iOS @property探究(一):基础详解介绍了@property的基本原理和使用方法,以及相关修饰符详解。 本文将会深入底层探究@property的本质。 在进入正题之前,先介绍一个clang编译器的命令 clang -rewrite-objc main.m 这个命令用于clang重写.m文件为.cpp文件。 @property深入代
WWWWDotPNG
2018/04/10
1K0
C语言__attribute__ ((constructor))和__attribute__ ((destructor))
一、gcc为函数提供了几种类型的属性,其中包含:构造函数(constructors)和析构函数(destructors),可带优先级。
IT工作者
2022/05/20
2.1K0
main函数真的是C程序的开始吗?
我们在学习和编写C程序时,都是从main函数开始,main函数作为入口函数已经深深地印在我们的脑海中,那么main函数真的是C程序的入口函数吗?带着这个问题我们先来看下面一段代码。 1. 实验程序 示例代码 #include <stdlib.h> #include <stdio.h> static void __attribute__ ((constructor)) beforeMain(void) { printf("Before main...\n"); } int main(void)
Linux兵工厂
2023/02/28
5370
main函数真的是C程序的开始吗?
《Objective-C高级编程》温故知新之"自动引用计数"
1、使用alloc、new、copy、mutableCopy的意味着自己生成的对象只有自己持有
Dwyane
2018/08/03
6350
《Objective-C高级编程》温故知新之"自动引用计数"
NSObject头文件解析 / 消息机制 / Runtime解读 (一)
上面是NSObject对象的头文件类部分, 可以看到还有一个NSObject protocol 我们也仔细看看都有什么协议方法@protocol NSObjec
周希
2019/10/15
1.3K0
What's New in LLVM 9
导语 :这绝不仅仅是一篇 WWDC 2017 Session 411 学习笔记。除了有关 LLVM 9.0 的新特性之外,还有关于静态分析器和 Clang 5 Objective-C ARC 的一点看
MelonTeam
2018/01/04
2.5K0
What's New in LLVM 9
神经病院Objective-C Runtime入院第一天—isa和Class
我第一次开始重视Objective-C Runtime是从2014年11月1日,@唐巧老师在微博上发的一条微博开始。
一缕殇流化隐半边冰霜
2018/08/30
8060
神经病院Objective-C Runtime入院第一天—isa和Class
弱符号__attribute__((weak))
弱符号是什么? 弱符号: 若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak symbol(弱符号),则这些全局符号不会引发重定义错误。链接器会忽略弱符号,去使用普通的全局符号来解析所有对这些符号的引用,但当普通的全局符号不可用时,链接器会使用弱符号。当有函数或变量名可能被用户覆盖时,该函数或变量名可以声明为一个弱符号。弱符号也称为weak alias(弱别名)。 attribute((weak))的作用 情况是这样的,碰到一个棘手的问题:我们不确定外部模块是否提供一个函数func
233333
2018/07/05
6.5K0
Objective-c 知识总结 -- @property
@property 只是一个编译器指令,意思是告诉编译器要干嘛,当然它的意思就是要求 Xcode 做属性声明了。
半纸渊
2018/09/04
1.4K0
Objective-c 知识总结 -- @property
iOS开发笔记(十三)
GPUImage的framework/Source目录下,有iOS和Mac两个文件夹,在iOS的工程中include了Mac文件夹的代码,会产生编译错误;将Mac文件夹去掉即可解决。
落影
2020/02/18
1.4K0
iOS开发笔记(十三)
Object-C中的黑魔法
在Swift中存在Option类型,也就是使用?和!声明的变量。但是OC里面没有这个特征,因为在XCODE6.3之后出现新的关键词定义用于OC转SWIFT时候可以区分到底是什么类型
君赏
2018/08/31
1.3K0
module & Swift库
一个module是机器代码和数据的最小单位,可以独立于其他代码单位进行链接 通常,module是通过编译单个源文件生成的目标文件。例如:当前的test.m被编译成目标文件test.o时,当前的目标文件就代表了一个module 这里有一个问题,module在调用的时候会产生开销,当使用一个静态库的时:@import TestStaticFramework; 如果静态库中包含许多.o文件。这岂不是会导入很多module? 当然不会。在静态链接的时候,也就是静态库链接到主项目或者动态库,最终生成可执行文件或
ruochen
2021/12/05
2.1K0
《C++中属性(Attribute)的深度探秘:提升代码质量与性能的利器》
在 C++的世界里,属性(Attribute)是一个强大却常常被忽视的特性。它为程序员提供了一种向编译器传达额外信息的方式,能够在代码的可读性、可维护性以及性能优化等方面发挥重要作用。随着 C++标准的不断演进,属性的种类也日益丰富。本文将深入探讨 C++中常见的属性及其应用场景。
程序员阿伟
2024/12/09
1010
KVO简单使用及其实现原理
在应用开发中,我们经常需要使用到,观察者模式,能监听某些对象属性的变化,进行相应的操作。在iOS中,OC为我们提供了一套更加简洁优雅的观察方式——KVO。
Oceanlong
2018/09/21
1.3K0
C语言进阶小技巧,弱符号和弱引用
__attribute__ 是一个编译器指令,其实是 GNU C 的一种机制,本质是一个编译器的指令,在声明的时候可以提供一些属性,在编译阶段起作用,来做多样化的错误检查和高级优化。
混说Linux
2023/02/24
9490
C语言进阶小技巧,弱符号和弱引用
结构体位域和__attribute__ ((__packed__))一起用
位域是一种节省空间的数据结构,是把一个数据类型按照二进制(二进位)划分为几个不同的区域,并说明每个区域的位数。
用户9736681
2023/09/01
2820
结构体位域和__attribute__ ((__packed__))一起用
iOS 编译器__Attribute__的入门指南
作者:小朋鸟 一、Attribute Attribute 是 GNU C 的一大特色。 所以这对于iOS来说这是一个什么东西? 这是一个可以给对象或函数声明特性的编译器指令,目的是让编译器做更多的错误检查和优化。 可设置函数属性(Function Attribute)、变量属性(Variable Attribute)、类型属性(Type Attribute) Swift 文档中的说明: Attributes provide more information about a declaration or ty
37手游iOS技术运营团队
2021/12/31
9810
iOS 编译器__Attribute__的入门指南
相关推荐
iOS_ __attribute__
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验