【iOS】static、const、extern关键字

static、const、extern关键字

)

前言

属性关键字博客,这里补充static、const、extern关键字的学习。

static

static既可以修饰局部变量,也可以修饰全局变量。用static修饰的变量我们称为静态变量。

静态变量:生命周期与程序运行时间相同,只初始化一次,在程序启动时创建,在程序结束时销毁。

修饰局部变量

称为静态局部变量。

对比一下下面两个代码:

objc 复制代码
-(int)add {
    int a = 0;
    a++;
    return a;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    for (int i = 0; i < 5; i++) {
        NSLog(@"%d", [self add]);
    }
}
objc 复制代码
-(int)add {
    static int a = 0;
    a++;
    return a;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    for (int i = 0; i < 5; i++) {
        NSLog(@"%d", [self add]);
    }
}
  • 代码一:a作为局部变量

在add代码块中,a作为一个局部变量,当我们重复调用add方法时,局部变量a也在不断地被分配空间初始化与销毁。当一次add方法结束后,即变量超出作用域时,a被销毁,下一次调用时又重新分配内存空间。

也就是说它的生命周期是函数调用时开始,函数结束后销毁。

底层逻辑实际上是调用add方法时,系统在栈区上分配一块内存,然后a = 0存入该内存,每次执行函数时,都是在栈上对a进行操作,当add方法返回时,栈被销毁,再次调用时,系统重新为a分配一次栈内存

  • 代码二:a作为静态局部变量

当使用static修饰局部变量时,变量被称为静态局部变量。与全局变量、静态全局变量一样,静态局部变量也是存储在静态存储区的。由于存储在静态存储区,因此这里的内存会直到程序结束才销毁。

也就是说它的生命周期是程序开始时分配,程序结束时销毁。

这里我们重点总结一下静态局部变量的特点:

  • 存储在静态内存区:静态局部变量与局部变量不同,它不存储在栈内存中,而是静态内存区域。静态内存区中的变量在程序运行期间一直存在。
  • 初始化只发生一次:静态局部变量的初始化仅在第一次进入它的作用域时发生。一旦被初始化,在函数的每次调用时,静态局部变量的状态都会得到保持,它们的值会被保留,一直保持不变,不会在后续函数调用中重新初始化。

修饰全局变量

称为静态全局变量。

下面我们通过代码对比一下有没有static修饰全局变量的区别:

  • 没有static修饰符

定义一个全局变量b,存储区在静态存储区,直到程序结束才销毁。

objc 复制代码
#import "AViewController.h"
#import "BViewController.h"

@interface AViewController ()

@end

@implementation AViewController

int b = 10;

在别的界面想调用它时,使用extern关键字来引用这个全局变量。

objc 复制代码
#import "BViewController.h"

@interface BViewController ()

@end

@implementation BViewController

extern int b;

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor greenColor];
    NSLog(@"%d", b);
}
  • 有static修饰符
objc 复制代码
@interface AViewController ()

@end

@implementation AViewController

static int b = 10;

这时我们想在别的地方调用b这个全局变量时,会出现报错:

这说明这时我们已经不能在其它文件中访问到这个全局变量b了。

总结

  • static修饰局部变量时,将分配在栈区改为分配在静态存储区,改变了局部变量的生命周期。
  • static修饰全局变量时,将源程序所有文件可见改为只在申明自己的文件可见,改变了作用域。

const

const主要强调当前变量无法被修改

objc 复制代码
const int c = 1;
c = 2;

这样就会出现提示我们c无法被修改的错误:

这样相当于用#define来定义,但const可以指定变量的类型,#define不能。

objc 复制代码
#define c 1

extern

extern主要是跨文件之间的变量共享和函数声明,也就是用于声明在其它源文件中定义的全局变量或函数。它用来告诉编译器某个标识符的定义在其它文件中,但在当前文件中要使用它。

声明全局变量

这个使用的demo已经在上面展示。

声明函数

表示函数定义在其它源文件,但允许在该源文件中调用定义的函数。

objc 复制代码
void test(void) {
    NSLog(@"Hello iOS");
}
objc 复制代码
extern void test(void);

- (void)viewDidLoad {
    [super viewDidLoad];
    test();
}

还有一种写法:

extern声明一般写在头文件中,因此可以在需要的源文件中包含该头文件,以便多个源文件可以共享相同的声明。

objc 复制代码
#ifndef Header_h
#define Header_h
extern int b;

#endif /* Header_h */
objc 复制代码
#import "BViewController.h"
#import "Header.h"

@interface BViewController ()

@end

@implementation BViewController
- (void)viewDidLoad {
  [super viewDidLoad];
  NSLog(@"%d", b);
}

总结

extern关键字使得不同文件可以共享相同的变量和函数,实现跨文件的共享和使用。

相关推荐
zzywxc7873 小时前
AI工具全景洞察:从智能编码到模型训练的全链路剖析
人工智能·spring·ios·prompt·ai编程
前端 贾公子4 小时前
《Vuejs设计与实现》第 16 章(解析器) 上
vue.js·flutter·ios
Digitally13 小时前
如何将大型音频文件从 iPhone 发送到不同的设备
ios·iphone
吴Wu涛涛涛涛涛Tao18 小时前
Flutter 实现「可拖拽评论面板 + 回复输入框 + @高亮」的完整方案
android·flutter·ios
搜狐技术产品小编20231 天前
CAEmitterLayer:iOS 中创建炫酷粒子效果的魔法工具
macos·ios·objective-c·cocoa
00后程序员张2 天前
iOS App 混淆与资源保护:iOS配置文件加密、ipa文件安全、代码与多媒体资源防护全流程指南
android·安全·ios·小程序·uni-app·cocoa·iphone
咕噜签名分发冰淇淋2 天前
内测分发是什么?
ios
2501_916007472 天前
Transporter App 使用全流程详解:iOS 应用 ipa 上传工具、 uni-app 应用发布指南
android·ios·小程序·https·uni-app·iphone·webview