OC中关键字extern、static、const探究

最近看了一篇blog:http://www.jianshu.com/p/2fd58ed2cf55 主要讲的就是这三个关键字的使用(以前自己从不用这几个关键字,是不是很low?),博主写的很好,在此致敬。但是我发现我对其中的extern、static理解不了,于是,自己爬网,总结了一下。希望对大家有帮助。

extern

extern(只能用来修饰全局变量)是一个大家很常见的东西,很多的第三方中都会出现这个关键字,以前只知道大概是跨文件引用的,其余的就基本不知道。废话少说,进入正题。对于extern我主要从三个方面来讲解。
1. 与.h文件的关系
2. extern引用变量
3. extern声明

1.与.h文件的关系
.h的用法:想必大家都很了解了,是为了更好的方便其他文件(类)去调用本文件中的变量、属性和方法。而extern也是为了实现变量和函数的跨文件引用。所以很有必要详细讲解一下.h文件和extern的用法。
对于.h文件,我想大家都很熟悉了,不做过多的解释,但是有一点很重要:如果你在.h文件中声明全局变量(在OC中是不合法的:主要指在@interface ExternModel : NSObject和@end之间,当然如果在他们两个之外也是可以声明的)代码如下:

这是一个.h文件
#import <Foundation/Foundation.h>
@interface ExternModel : NSObject
  //  这个是不合法的:因为OC的类会将这个全局变量当做成员属性来处理,而成员属性是需要加{}的,所以不合法
      NSString *lhString;//声明全局变量的时候默认带有extern,这里必须显式声明
@end

所以正确的写法应该是:(如果还在.h中声明全局变量)

#import <Foundation/Foundation.h>
@interface ExternModel : NSObject
     extern NSString *lhString;//这里由于带有extern所以会被认为是全局变量
@end
常用用法(.h结合extern联合使用):
1. 如果在.h文件中声明了extern全局变量,那么在同一个类中的.m文件对全局变量的赋值必须是:数据类型+变量名(与声明一致)=XXXX结构。并且在调用的时候,必须导入.h文件。代码如下:

ExternModel.h

#import <Foundation/Foundation.h>
@interface ExternModel : NSObject
      extern NSString *lhString;
@end

ExternModel.m

#import "ExternModel.h"
@implementation ExternModel
       NSString *lhString=@"hello";
@end

调用的时候:例如:在viewController.m中调用,则可以引入:ExternModel.h,否则无法识别全局变量。当然也可以通过不导入头文件的方式进行调用(通过extern调用)。

  1. extern引用变量
    extern具备与.h文件很相似的跨文件访问的功能,但是.h文件不单单局限于范文全局变量,而extern则必须是全局变量(静态+非静态)。
    如果在其他文件中访问一个类的全局变量,可以不用导入.h文件,通过extern去直接访问。
    例子:同样还是在ViewController.m中访问,此时不需要去导入头文件,代码如下(此时ExternModel代码如上):
    #import "ViewController.h"

    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
          [super viewDidLoad];
           extern NSString *lhString;
           NSLog(@"%@",lhString);
    }
    @end
    

输出结果:
2016-03-18 13:37:45.404 ExternTest[1490:180870] hello
可见在不通过.h的情况下去访问全局变量,可以通过extern实现。

  1. extern声明
    extern声明,仅适于修饰全局变量,不能去修饰其他的变量。一般情况下默认,定义的全局变量都带有extern,所以不过多解释。
const

const是用来修饰常量的,这一点注意与宏的区别(苹果推荐我们不要将字符串常量抽成宏):
(以下总结引用自:http://www.jianshu.com/p/2fd58ed2cf55 因为总结的很好)

1.编译时刻:宏是预编译(编译之前处理),const是编译阶段。

2.编译检查:宏不做检查,不会报编译错误,只是替换,const会编译检查,会报编译错误。

3.宏的好处:宏能定义一些函数,方法。 const不能。

4.宏的坏处:使用大量宏,容易造成编译时间久,每次都需要重新替换。

const的介绍:
1. const仅仅用来修饰右边的变量(基本数据变量p,指针变量*p)
2. 被const修饰的变量是只读的。
代码如下:

  - (void)viewDidLoad { 
          [super viewDidLoad]; 
          // 定义变量 
          int a = 1; 
          // 允许修改值 
          a = 20; 

          // const两种用法 
          // const:修饰基本变量p 
          // 这两种写法是一样的,const只修饰右边的基本变量b 
          const int b = 20; // b:只读变量 
          int const b = 20; // b:只读变量 
          // 不允许修改值 
          b = 1; 
          // const:修饰指针变量*p,带*的变量,就是指针变量. 
          // 定义一个指向int类型的指针变量,指向a的地址 
          int *p = &a; 
          int c = 10; 
          p = &c; 

          // 允许修改p指向的地址 
          // 允许修改p访问内存空间的值 
          *p = 20; 
          // const修饰指针变量访问的内存空间,修饰的是右边*p1,
          // 两种方式一样 
          const int *p1; // *p1:常量 p1:变量 
          int const *p1; // *p1:常量 p1:变量 
          // const修饰指针变量p1 
          int * const p1; // *p1:变量 p1:常量 
          // 第一个const修饰*p1 第二个const修饰 p1 
          // 两种方式一样 
          const int * const p1; // *p1:常量 p1:常量 
          int const * const p1; // *p1:常量 p1:常量
 }
static修饰全局变量

1.在全局变量前加static,全局变量就被定义成为一个全局静态变量(全局变量和静态全局变量的生命周期是一样的,都是在堆中的静态区,在整个工程执行期间内一直存在)
特点如下:
1)存储区:静态存储区没变(静态存储区在整个程序运行期间都存在);
2)作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。非静态全局 变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。

 好处:   
1)不会被其他文件所访问,修改;
2)其他文件中可以使用相同名字的变量,不会发生冲突。

2.static修饰局部变量
在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。
特点如下:
1)存储区:有栈变为静态存储区rw data,生存期为整个源程序,只能在定义该变量的函数内使用。退出该函数后, 尽管该变量还继续存在,
但不能使用它;
2)作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束。

3.static修饰函数
在函数的返回类型前加上关键字static,函数就被定义成为静态函数。
函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用
好处:
1)其他文件中可以定义相同名字的函数,不会发生冲突
2) 静态函数不能被其他文件所用。
在我们这篇博客中主要关注于OC中三个关键字的常用方法。以下将是OC中常用方法的总结:

static和const的联合使用
  • static与const作用:声明一个只读的静态变量
  • 开发使用场景:在一个文件中经常使用的字符串常量,可以使用static与const组合
    具体参考bolg:http://www.jianshu.com/p/2fd58ed2cf55 中的static与const的联合使用
extern和const的联合使用
   作用:extern与const组合:只需要定义一份全局变量,多个文件共享。并且全局常量只被定义一次,分配一次内存空间。

代码如下:
ExternModel.h

  #import <Foundation/Foundation.h>
  @interface ExternModel : NSObject
      extern NSString * const lhString;
  @end

ExternModel.m

  #import "ExternModel.h"
  @implementation ExternModel
       NSString * const lhString=@"hello";
  @end

调用的时候通过导入.h文件进行调用。

欢迎关注我的个人微信公众号,免费送计算机各种最新视频资源!你想象不到的精彩!


0.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • 1 原理 1.1 首先,关于声明和定义的区别。 这种写法(函数原型后加;号表示结束的写法)只能叫函数声明而不能叫函...
    Pitfalls阅读 6,448评论 2 12
  • 一、前言 阅读别人的代码(一些优秀的源码)总能发现一些常见的关键字,随着编程经验的积累大部分还是知道是什么意思的,...
    hiigirl阅读 224评论 0 1
  • 前段时间一直很想读些管理类的书籍,朋友们大都推荐的是西式或日式的畅销书。不可否认西式管理有他的过人之处,日式管理的...
    KKarin阅读 654评论 0 0
  • 今天特别累,特别不想写,但如果不写,那以后就很难坚持。 生活老师在早读前将孩子们送到教室,告诉我,叶永添和易世博两...
    优妮妮阅读 247评论 1 0
  • 终于在前后拖延这么久,中间兼杂许多事之后,完整看完了人生中第二次如此挚爱的书,杨熹文的《请尊重一个姑娘的努力》。 ...
    张小风阅读 357评论 6 1