宏定义¶
头文件加保护¶
预处理指令
头文件加保护,防止多重包含,避免重复编译头文件。
一般是这样的形式
#ifndef XXXXX_H // 如果没有定义 XXXXX_H
#define XXXXX_H // 先定义 XXXXX_H,那么下一次编译到这个头文件的时候上一句条件不成立,下面的内容就不会再编译了。
// 头文件中的代码
#endif
在 C++ 中,可以用#pragma once
来代替,使用了 #pragma once
之后就可以不去判断有没有编译过这个头文件,由编译器自己判断。
只要写头文件 都要写头文件的保护。
宏、全局变量、常量的选择¶
全局共用一些数据时,可以用宏、变量、常量
- 宏:只是在预处理器里进行文本替换,没有类型,不做任何类型检查,编译器可以对相同的字符串进行优化。只保存一份到 .rodata 段。甚至有相同后缀的字符串也可以优化,你可以用GCC 编译测试,"Hello world" 与 "world" 两个字符串,只存储前面一个,取的时候只需要给前面和中间的地址。如果是整形、浮点型会有多份拷贝,但这些数写在指令中,占的只是代码段而已,大量用宏会导致二进制文件变大。
- 全局变量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以被修改,在编译阶段会执行类型检查。
- 常量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以根据const修饰的位置设定能否修改,在编译阶段会执行类型检查。
尽量使用const,看苹果api使用常量多点,如下:
UIKIT_EXTERN NSString *const UIKeyboardFrameBeginUserInfoKey API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos); // NSValue of CGRect
常量¶
1、全局常量¶
不管定义在任何文件夹,外部都能访问
在ViewController.m源文件中定义一个 haha 字符串全局常量:
NSString *const haha = @"hahahaha";
在AppDelegate中访问:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
extern NSString *haha;
NSLog(@"我是haha:%@",haha);//我是haha:hahahaha
return YES;
}
一般项目中,定义全局常量,会写在独立文件里
HHConst.h文件
UIKIT_EXTERN NSString *const NETWORK_ERROR;
HHConst.m文件
NSString *const NETWORK_ERROR = @"网络出错,请稍后再试";
extern¶
extern会声明一个工程内全局共享变量,但不给予实现,也就是不会为其申请内存,等到定义时才会申请内存空间。
// .h
extern int var;
// .m
int var = 10;
2、局部常量¶
用static
修饰后,不能提供外界访问,只能本文件内访问。
例如:
在ViewController定义一个 haha 字符串局部常量:
#import "ViewController.h"
static const NSString *haha = @"hahahaha";
const修饰位置不同,代表什么?¶
const NSString *HSCoder = @"汉斯哈哈哈";
"*HSCoder"不能被修改, "HSCoder"能被修改
NSString const *HSCoder = @"汉斯哈哈哈";
"*HSCoder"不能被修改, "HSCoder"能被修改
NSString * const HSCoder = @"汉斯哈哈哈";
"HSCoder"不能被修改,"*HSCoder"能被修改
结论:const右边的总不能被修改
定义一个常量,其它文件可以访问,但是不能修改
NSString * const HSCoder = @"汉斯哈哈哈";