【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关键字使得不同文件可以共享相同的变量和函数,实现跨文件的共享和使用。

相关推荐
坏小虎2 小时前
Expo 快速创建 Android/iOS 应用开发指南
android·ios·rn·expo
光影少年3 小时前
Android和iOS原生开发的基础知识对RN开发的重要性,RN打包发布时原生端需要做哪些配置?
android·前端·react native·react.js·ios
北京自在科技3 小时前
Find My 修复定位 BUG,AirTag 安全再升级
ios·findmy·airtag
Digitally4 小时前
如何不用 USB 线将 iPhone 照片传到电脑?
ios·电脑·iphone
Sim148016 小时前
iPhone将内置本地大模型,手机端AI实现0 token成本时代来临?
人工智能·ios·智能手机·iphone
Digitally18 小时前
如何将 iPad 上的照片传输到 U 盘(4 种解决方案)
ios·ipad
报错小能手21 小时前
ios开发方向——swift并发进阶核心 @MainActor 与 DispatchQueue.main 解析
开发语言·ios·swift
LcGero21 小时前
Cocos Creator 业务与原生通信详解
android·ios·cocos creator·游戏开发·jsb
ii_best21 小时前
lua语言开发脚本基础、mql命令库开发、安卓/ios基础开发教程,按键精灵新手工具
android·ios·自动化·编辑器
用户223586218202 天前
WebKit WebPage API 的引入尝试与自研实现
ios