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

相关推荐
2501_9159214317 小时前
iOS 26 CPU 使用率监控策略 多工具协同构建性能探索体系
android·ios·小程序·https·uni-app·iphone·webview
狂团商城小师妹17 小时前
JAVA国际版同城打车源码同城服务线下结账系统源码适配PAD支持Android+IOS+H5
android·java·ios·小程序·交友
游戏开发爱好者817 小时前
iOS 应用逆向对抗手段,多工具组合实战(iOS 逆向防护/IPA 混淆/无源码加固/Ipa Guard CLI 实操)
android·ios·小程序·https·uni-app·iphone·webview
00后程序员张17 小时前
iOS 文件管理与导出实战,多工具协同打造高效数据访问与调试体系
android·macos·ios·小程序·uni-app·cocoa·iphone
AirDroid_cn1 天前
在 iOS 18 中,如何将锁屏底部的 “手电筒” 替换为其他应用?
ios
芝麻开门-新起点1 天前
Android 和 iOS 系统版本及开发适配
android·ios·cocoa
2501_915918411 天前
iOS描述文件功能解析
android·macos·ios·小程序·uni-app·cocoa·iphone
汉秋1 天前
SwiftUI动画之使用 navigationTransition(.zoom) 实现 Hero 动画
ios·swiftui
加油乐2 天前
解决 iOS 端输入框聚焦时页面上移问题
前端·javascript·ios
电话交换机IPPBX-3CX2 天前
电话交换机软件 3CX iOS 应用 V5.4 Beta 更新
ios·软件更新·ip pbx·电话交换机