OC中的关键字: static extern const

1.static

1.1 static修饰局部变量

  • 修饰方法中的局部变量: 如果方法中的局部变量被static修饰,那么这个变量就会变成静态局部变量,储存在常量区,当方法执行完毕之后,不会回收,下次再执行这个方法的时候,直接使用,就不会再声明了
    举个例子:
//Teacher.h文件 只声明了一个方法
#import <Foundation/Foundation.h>
@interface Teacher : NSObject
-(void)sayHi;
@end
//Teacher.m文件 实现方法 
#import "Teacher.h"
@implementation Teacher
- (void)sayHi
{
    int num = 12;
    NSLog(@"num = %d",num);
    num++;
}
@end
#import <Foundation/Foundation.h>
#import "Teacher.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
       //实例化对象 调用sayHi的方法两次 查看输出的结果
        Teacher *teacher = [[Teacher alloc]init];
        [teacher sayHi];
        [teacher sayHi];
    }
    return 0; 
}

输出的结果:
2017-05-27 19:37:56.951110+0800 property[17992:628125] num = 12
2017-05-27 19:37:56.951692+0800 property[17992:628125] num = 12

两次的结果都是12, 这次我们在sayHi方法的局部变量中加入static关键字,再次打印输出,看看结果会是什么

//Teacher.m文件 实现方法 
#import "Teacher.h"
@implementation Teacher
- (void)sayHi
{
    static int num = 12;    //加入了static关键字
    NSLog(@"num = %d",num);
    num++;
}
@end

继续调用两次sayHi的方法,打印输出的结果为:
2017-05-27 19:44:57.023325+0800 property[18082:632493] num = 12
2017-05-27 19:44:57.023478+0800 property[18082:632493] num = 13

注意 :

当我们不加static关键字时,在方法在执行完了之后,方法内的局部变量就会被回收, 再此调用的时候,就会再次生成一个新的局部变量,所以两次的值一样
加了static之后,局部变量就变成了静态变量,只初始化一次,下一次依据上一次的结果
不能修饰属性 :

@interface Teacher : NSObject
{
    static NSString *name; //这样是会报错的
//  报错信息: Type name does not allow storage class to be specified
}

不能修饰方法

1.2 static修饰全局变量

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


2. extern

2.1 extern声明

extern声明: 仅适于修饰全局变量,不能去修饰其他的变量。
工作原理: 先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找

2.2 extern和.h文件的关系

.h文件的作用就是为了更好的方便其他文件(类)去调用本文件中的变量、属性和方法。而extern也是为了实现变量和函数的跨文件引用
如果你在.h文件的@interface XXX : NSObject和@end之间声明全局变量是不合法的:

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

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

// Hello.h文件
#import <Foundation/Foundation.h>
@interface Hello : NSObject
     extern NSString *myString;//这里由于带有extern所以会被认为是全局变量
@end
//Hello.m文件
#import "Hello.h"
@implementation Hello
       NSString *myString=@"hello";
@end

2.3 extern引用变量

extern具备与.h文件很相似的跨文件访问的功能,但是.h文件不单单局限于范文全局变量,而extern则必须是全局变量(静态+非静态)
如果在其他文件中访问一个类的全局变量,可以不用导入.h文件,通过extern去直接访问。

#import "ViewController.h"
@interface ViewController ()
@end

@implementation ViewController

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

输出结果: ` 2017-05-27 21:23:47.424 Test[1490:180870] hello


3. const

3.1使用方法:

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:常量
 }

3.2 const与宏(define)的区别

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

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

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

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

4.static与const联合使用

static与const作用: 声明一个只读的静态变量
开发使用场景: 在一个文件中经常使用的字符串常量,可以使用static与const组合, 可以理解为代替宏的使用

5.extern与const联合使用

开发中使用场景: 在多个文件中经常使用的同一个字符串常量,可以使用extern与const组合。
原因:

  • static与const组合:在每个文件都需要定义一份静态全局变量。
  • extern与const组合 : 只需要定义一份全局变量,多个文件共享。

全局常量正规写法:开发中便于管理所有的全局变量,通常搞一个GlobeConst文件,里面专门定义全局变量,统一管理,要不然项目文件多不好找。


本文部分内容借鉴了以下网址
袁峥Seemygo 韩俊强 liyubao160

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值