__weak修饰符
前言
在 HAL 库中,很多回调函数前面使用__weak 修饰符。
weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”。
加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,
那么编译器就会执行__weak 声明的函数,并且编译器不会报错。
举个例子
我们打开工程模板,找到并打开文件stm32f4xx_hal.c 文件,里面定义了一个函数 HAL_MspInit,定义如下:
__weak void HAL_MspInit(void)
{
__IO uint32_t tmpreg = 0x00;
UNUSED(tmpreg);
}
可以看出,HAL_MspInit 函数前面有加修饰符__weak。同时,在该文件的前面有定义函数HAL_Init,并且 HAL_Init 函数中调用了函数 HAL_MspInit。
HAL_StatusTypeDef HAL_Init(void)
{
…//此处省略部分代码
HAL_MspInit();
return HAL_OK;
}
如果我们没有在工程中其他地方重新定义 HAL_MspInit()函数,那么 HAL_Init 初始化函数执行的时候,会默认执行 stm32f4xx_hal.c 文件中定义的 HAL_MspInit 函数,而这个函数没有任何控制逻辑。 如果用户在工程中重新定义函数 HAL_MspInit,那么调用 HAL_Init 之后,会执行用户自己定义的 HAL_MspInit 函数而不会执行 stm32f4xx_hal.c 默认定义的函数。也就是说,表面上我们看到函数 HAL_MspInit 被定义了两次,但是因为有一次定义是弱函数,使用了__weak修饰符,所以编译器不会报错。
总结
__weak 在回调函数的时候经常用到。这样的好处是,系统默认定义了一个空的回调函数,保证编译器不会报错。同时,如果用户自己要定义用户回调函数,那么只需要重新定义即可,不需要考虑函数重复定义的问题,使用非常方便,在 HAL 库中__weak 关键字被广泛使用。
应用
创建一个工程如下: 
在weakTest.c中定义一个weak函数,并且定义一个调用该weak函数的函数
__weak void weakFunctioin(void){    //定义为__weak类型的函数
    logInfo("print weakFunction\r\n");
}
int weakFunctionTest(unsigned int tst){
    logInfo("print A\r\n");
    if (tst) {
        logInfo("print B\r\n");
        weakFunctioin();    //调用函数
        logInfo("print C\r\n");
    }else{
        logInfo("print D\r\n");
    }
    logInfo("print E\r\n");
    return ;
}
在main.c文件中,定义main函数及weakFunctionTest函数:
void weakFunctioin(void){    //定义为正常的函数
    logInfo("print nonWeakFunction\r\n");
    return;
}
int main(void){
    logInit(logLevelDebug);
    logInfo("Build @ %s %s,system start\r\n", __DATE__, __TIME__);
    weakFunctionTest();
    logInfo("Build @ %s %s,system stop\r\n", __DATE__, __TIME__);
    while();
    return ;
}
运行时打印为:
-I: Build @ Jun ::,system start
-I: print A
-I: print B
-I: print nonWeakFunction
-I: print C
-I: print E
-I: Build @ Jun ::,system stop
参考:
https://blog.csdn.net/baicaiaichibaicai/article/details/73129417?utm_source=blogxgwz1
https://blog.csdn.net/qq562029186/article/details/76216311#
__weak修饰符的更多相关文章
- __weak 修饰符
		在 HAL 库中,很多回调函数前面使用__weak 修饰符,这里我们有必要给大家讲解__weak 修饰符的作用. weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一 ... 
- __block和__weak修饰符的区别
		block下循环引用的问题 __block本身并不能避免循环引用,避免循环引用需要在block内部把__block修饰的obj置为nil __weak可以避免循环引用,但是其会导致外部对象释放了之后, ... 
- __weak与__block修饰符区别
		API Reference对__block变量修饰符的解释,大概意思: 1.__block对象在block中是可以被修改.重新赋值的. 2.__block对象在block中不会被block强引用一次, ... 
- IOS开发 __weak与__block修饰符到底有什么区别
		API Reference对__block变量修饰符有如下几处解释: //A powerful feature of blocks is that they can modify variables ... 
- Objective C中的ARC的修饰符的使用---- 学习笔记九
		#import <Foundation/Foundation.h> @interface Test : NSObject /** * 默认的就是__strong,这里只是做示范,实际使用时 ... 
- [转]黑幕背后的__block修饰符
		http://www.cocoachina.com/ios/20150106/10850.html 我们知道在Block使用中,Block内部能够读取外部局部变量的值.但我们需要改变这个变量的值时,我 ... 
- ARC下的所有权修饰符
		ARC有效时,id类型必须加上所有权修饰符 下面为三种等效的声明,为了便于和二级指针的情况联系起来,采用第一种. NSError * __weak error = nil; NSError __wea ... 
- iOS 基础日记-修饰符
		今晚随便温习了一下iOS 基础关于修饰符这块的东西,下面简单的来描述一下,其中有的也是在网络学习到的: strong与weak是由ARC新引入的对象变量属性 ARC的解释:ARC引入了新的对象的生命周 ... 
- 01  (OC)*  @property 后面可以有哪些修饰符?
		一:@property 后面可以有哪些修饰符? 1:线程安全的: atomic,nonatomic 2:访问权限的 readonly,readwrite 3:内存管理(ARC) assign, cop ... 
随机推荐
- [置顶]
        使用 maven 插件 maven-shade-plugin 对可执行 java 工程及其全部依赖 jar 进行打包
			作者:chenzhou123520 出处:http://chenzhou123520.iteye.com/blog/1706242 使用 maven 插件 maven-shade-plugin 对 j ... 
- C语言 将十六进制字符串转为十六进制数 (二进制、十进制都适用)
			主要利用 long int strtol(const char *nptr,char **endptr,int base); 函数 函数说明: 参数base范围从2至36,或0.参数base代表采用的 ... 
- nginx虚拟主机的配置不生效
			这个坑找了好久,今天终于找到了问题所在. 一般虚拟主机配置文件是vhost里面单独写一个网站名.conf,然后在nginx最后include vhosts/*.conf 引用. 但是我这里的vhost ... 
- arXiv 2015深度学习年度十大论文
			由康奈尔大学运营维护着的arXiv网站,是一个在学术论文还未被出版时就将之向所有人开放的地方.这里汇聚了无数科学领域中最前沿的研究,机器学习也包括在内.它反映了学术界当前的整体趋势,我们看到,近来发布 ... 
- COGS——T 1175. [顾研NOIP] 旅游电车
			http://www.cogs.pro/cogs/problem/problem.php?pid=1175 ★★☆ 输入文件:buss.in 输出文件:buss.out 简单对比时间限制: ... 
- Spring表达式语言SpEL简单介绍
			Spring3引入了Spring表达式语言(Spring Expression Language,SpEL). SpEL有非常多特性.比較经常使用的包含: 1.使用bean的id来引用bean, 以下 ... 
- iOS知识点汇总
			1.怎样追踪app崩溃率.怎样解决线上闪退 当iOS设备上的App应用闪退时.操作系统会生成一个crash日志.保存在设备上.crash日志上有非常多实用的信息,比方每个正在运行线程的完整堆栈跟踪信息 ... 
- DICOM医学图像处理:fo-dicom网络传输之 C-Echo and C-Store
			背景: 上一篇博文对DICOM中的网络传输进行了介绍.主要參照DCMTK Wiki中的英文原文.通过对照DCMTK与fo-dicom两个开源库对DICOM标准的详细实现,对理解DICOM标准有一个更直 ... 
- NOIP 2012 T2 国王游戏 (贪心+高精)
			思路: 呃呃网上那么多题解写得都不错-.. 就是高精 巨坑... 这里展出的是任氏高精(纯自己yy滴) //By SiriusRen #include <cstdio> #include ... 
- Sql Server创建主键失败:CREATE UNIQUE INDEX 终止,因为发现对象名称 '[PPR_BasicInformation]' 和索引名称 '[PK_PPR_BasicInformation]' 有重复的键(E)
			这种问题是由于主键设置了唯一性,而数据库中主键列的值又有重复的值,重复值为E,改掉其中一个值就可以了. 
