美文网首页iOS学习iOS归纳比较
const / define / static / extern

const / define / static / extern

作者: iOS_成才录 | 来源:发表于2015-11-12 19:50 被阅读601次

一、全局变量 / 宏 / 常量 比较

  • 全局变量:

int age = 20; 缺点:能修改,优点:内存中只保存一份,不会产生很多临时空间

+ 宏:
```objc
#define age 20 优点:不可修改,缺点:会产生很多临时的内存空间
  • 常量:
const int age = 20;优点:不能修改只读,且内存中只会有一份存储空间 
// 等价于 int const age = 20;
  • 注意:


    Snip20150906_60.png
    Snip20150906_61.png
    Snip20150906_62.png

二、 总结:

  • const:const只修饰它右边的内容,被const修饰的内容都是常量。

  • static:

    • 被static修饰的全局变量/常量,仅限当前文件访问
    • 被static修饰的局部变量,只会占用一块内存,整个程序运行不会销毁,只会初始化一次。
  • extern:可以引用一个全局变量/常量

  • 常量使用潜规则

    • 常量必须在编译时就必须有确定的值

三、作用域

  • int money; 全局变量:
  • 默认情况下,全世界都是可以访问的,不仅限某一个类,利用extern可以引用一个全局变量,如:extern int money; =>引用某个类的全局变量money。而且我们可以对全局变量money进行修改。
  • const int money ;

    • 默认情况下,全世界都可以用,但是不可用改,只读:extern const int money; =》 只读不可改。

    • 注意:类中函数也是:全世界都可以访问的,我们只需要引用即可调用。引用函数写法:extern void eat();

  • static int money;

    • 被static修饰的全局变量:作用域:只限制在当前文件中访问使用。
  • static int const money;

    • 被static修饰的全局常量:仅限当前文件中使用,且不可改,只读

四、 应用:

1. 字符串常量
// cellID 字符串被const 修饰了,,字符串类型的cellID不可改
 NSString * const cellID = @"cellTagID"; // 注意:NSString字符串 == 一个指针指向它

 int const *age = 10; // age 不可修改
  • 总结写法:const 和 变量 紧挨着避免不必要的错误

  • 常量使用潜规则

    • 常量必须在编译时就必须有确定的值
// 是错误的,因为[UIColor redColor] -> 是在运行时才确定的,不符合常量使用的潜规则
UIColor *const JPGlobalColor = [UIColor redColor];

// 宏定义正确
#define JPGlobalColor [UIColor redColor]
2. cell标识
// JPHomeCellID,仅限当前文件,不可改,只占一份内存空间。
static NSString *const JPHomeCellID = @"JPHomeCellID";
3. URL字符串,保证全世界内存只有一份且全世界都可以访问,且不可更改
3.1 思路分析
  • 全世界都可以访问:所有不能用static(仅限某一个类访问)
  • 全世界内存都只有一块:不能用#define宏(多次拷贝,会存在多块内存)定义;
  • 不可更改:定义为常量
3.2 解决方案
  • 方案一(不可行):定义常量放入pch文件 : 缺点-> 所有的类引用,重复定义
// 不可行,因为pch文件内容会拷贝到每一个文件中,这样会引起重复定义问题
NSString *const  JPRequestURL = @"http://baidu.com";
  • 方案二(不可取):麻烦
    • 1.常量的定义放在一个const.m文件中

NSString *const JPRequestURL = @"http://baidu.com";

   - 2.然后在pch文件中引用const.m文件中定义的常量
```objc
 extern NSString *const  JPRequestURL;  // extern 引用常量,这样就解决的只在pch中定义常量引起的重复定义的问题,而且保证了一份内存
  • 3.缺点:如果有100个,就需要在const.m文件中定义100个常量,然后在pch文件中利用extern引用100个定义的常量
  • 方案三(最终方案):
    • 简单,解决了方案二中引用麻烦的问题
    • 步骤:
      • 在const.m(定义所有常量)中定义常量的值,

NSString *const JPRequestURL = @"http://baidu.com";

    + 在const.h文件(引用定义的全局常量)中引用定义的全局常量
 ```objc
#import <UIKit/UIKit.h>
// URL
UIKIT_EXTERN NSString *const JPRequestURL;
+ 在pch文件中导入const.h文件即可
#import "const.h"
4. 定义Rect结构体变量commonRect,要求只有本文件中能访问,且不可修改
  • 使用全局处理,取代宏定义

  • 思路分析:只有本文件中能访问 -> static修改commonRect变量;不可修改 -> 且还用const修改;

  • 注意:Rect结构体创建有两张方式 : CGRectMake(0,0,50,50) ->运行时才能确定其值;{{0,0},{50,50}} ->编译时就确定其值了。如何选择呢?

    • 很明显,我们需要定义常量,还记得常量的潜规则是什么吗?-> 常量的值必须编译时就确定,否则会报错的,所以我们只能通过{{0,0},{50,50}}方式创建结构体常量。
  • 实现

// 正确
static CGRect const commonRect = {{0,0},{50,50}}; 
// 错误
static CGRect const commonRect = CGRectMake(0,0,50,50);

五、全局常量写法

1. 仅限本文件中访问
  • 在.m中写下面代码
static 类型 const 常量名 = 常量值;
2. 全世界都要访问
  • 1>在const.m文件中,(const.m定义所有全局常量)
#import <UIKit/UIKit.h>
类型 const 常量名 = 常量值;
.........
  • 2>在const.m文件中,写下列代码(引用所有全局常量)
#import <UIKit/UIKit.h>
UIKIT_EXTERN 类型 const 常量名;
.........
  • 3>在pch文件中包含const.m文件,导入头文件
#import "const.h"

相关文章

网友评论

  • 鬼丶白:你好 你写的 3. URL字符串,保证全世界内存只有一份且全世界都可以访问,且不可更改。
    这一条我把NSString *const JPRequestURL = @"http://baidu.com&quot;;写到OC 的HeaderFile.h里面 然后把#import "HeaderFile.h"写到pch里面不行吗?
    iOS_成才录:@soime #define是宏定义,重点不是定义在哪,常量定义是常量,而是它们之间的差别和各自使用场景
    鬼丶白:@iOS_成才录 那么使用#define 定义的写在.h 里面还是.m 里面啊
    iOS_成才录:@soime 你写的不对可能,.h文件,把类定义与实现自动生成的代码都删除 ,.h与.m中头只添加#import <UIKit/UIKit.h>,然后按照我上面实现定义与引用
  • 437aff410919:你好,作者。对于这句话“被static修饰的全局变量:作用域:只限制在当前文件中访问使用。”,这里我有一个疑问。
    只限制在当前文件中访问使用,我对此不太理解,我可以在.h文件声明一个static修饰的全局变量。然后在其他文件声明一下这个头文件,然后使用这个static变量。因为在文章里面没看到有人提到过在.h那里声明这个static变量,所以这样做会有什么问题吗?这样算不算可以不在当前文件中访问使用?虚心求解... :flushed:
    437aff410919:@iOS_成才录 谢谢,明白了。
    iOS_成才录:@Tosaka乐园 按照面向对象思想,定义的属性 是 属于类的对象,而static 是 不可以修饰属性可以这么说,当前 你 可以在 @interface上面定义 static 变量,那就不算是 某个类所有吧,是全局的变量, 我上面说的只是在 .m中定义 变量,不知道你说的我理解了没。
  • MonsterNanny:理清了 thx~

本文标题:const / define / static / extern

本文链接:https://www.haomeiwen.com/subject/acmxhttx.html