iOS-static const extern与多个关键字的使用

静态变量、静态常量、全局变量

静态变量
  • 当我们希望一个变量的作用域不仅仅是作用域某个类的某个对象,而是作用域整个类的时候,这时候就可以使用静态变量。
  • 静态变量也可以被称为内部全局变量,意思就是静态变量是在所定义的位置是全局的,但是不可以被其他文件访问。

static

  • 修饰局部变量:
    1.延长局部变量的生命周期,程序结束才会销毁。
    2.局部变量只会生成一份内存,只会初始化一次。
    3.改变局部变量的作用域。
  • 修饰全局变量
    1.只能在本文件中访问,修改全局变量的作用域,生命周期不会改
    2.避免重复定义全局变量

static修饰的变量,是一个私有的全局变量。
C或者Javastatic关键字修饰的变量,可以使用类名直接拿到这个变量对象,在其他类中可以进行修改。但是在OCstatic修饰的变量是不能通过类名直接访问的,它只作用于它声明所在的.m文件中。
static修饰的变量必须放在@implementation外面或方法中,它只在程序启动初始化一次。

static int num;

静态常量

const

  • const修饰的变量是不可变的,如果需要定义一个时间间隔的静态常量,就可以使用const修饰。
  • 常量像定义普通变量一样只不过加了关键字const,常量要定义在源文件中(.m文件)。只要常量是定义在函数或方法之外,那常量也是外部全局变量,是可以被其他文件使用的,其他文件使用外部全局常量与普通的外部全局变量使用方式一样,先用extern关键字进行声明。
NSString * const myName = @"wxk";

如果试图修改myName编译器则会报错。

如果我们定义一个字符串类型的静态常量就要注意了,这两种写法是一样的,而且是可以修改的。

static NSString const * myName = @"wxk";
static const NSString * myName = @"wxk";

这两种写法const修饰的是* myName,*是指针指向符,也就是说此时指向内存地址是不可变的,而内存保存的内容时可变的。
所以我们应该这样写:

static NSString * const myName = @"wxk";

当我们定义一个对象类型常量的时候,要将const修饰符放到*指针指向符后面。
结论:const右边的总不能被修改

想了解更多点击关于iOS 宏(define)与常量(const)的正确使用


全局变量

** extern**

  • extern作用:
    extern修饰的变量,是一个全局变量。
    只是用来获取全局变量(包括全局静态变量)的值,不能用于定义变量
  • extern工作原理:
    先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找。
比如在 ViewController的.m文件里 定义myName
#import "ViewController.h"
#import "FirstViewController.h"
NSString * myName = @"wwxxkk";
@interface ViewController ()
@end

(我们从ViewController跳转到FirstViewController)

在FirstViewController的.m文件里使用extern查找myName,然后打印myName的值
#import "FirstViewController.h"
extern NSString * myName;
@interface FirstViewController ()
@end
@implementation FirstViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"myName = %@",myName);
    //2017-06-19 21:43:12.434 112233[4696:381459] myName = wwxxkk
}
@end

static与extern是一对“水火不容”的家伙,也就是说extern和static不能同时修饰一个变量;其次,static修饰的全局变量声明与定义同时进行,也就是说当你在头文件中使用static声明了全局变量后,它也同时被定义了;最后,static修饰全局变量的作用域只能是本身的编译单元,也就是说它的“全局”只对本编译单元有效,其他编译单元则看不到它.


关键字

  • @property
    @property 其实就是在编译阶段由编译器自动帮我们生成ivar成员变量getter方法,setter方法。
    使用“自动合成”( auto synthesis)这个过程由编译器在编译阶段执行自动合成,所以编译器里看不到这些“合成方法”(synthesized method)的源代码。除了生成getter、setter方法之外,编译器还要自动向类中添加成员变量(在属性名前面加下划线,以此作为实例变量的名字)反编译相关的代码大致生成:

OBJC_IVAR_$类名$属性名称 // 该属性的“偏移量” (offset),这个偏移量是“硬编码” (hardcode),表 示该变量距离存放对象的内存区域的起始地址有多远

实际流程:
每次增加一个属性,系统都会在 ivar_list 中添加一个成员变量的描述,在 method_list 中增加 setter 与 getter 方法的描述,在 prop_list 中增加一个属性的描述,计算该属性在对象中的偏移量,然后给出 setter 与 getter 方法对应的实现。
在 setter 方法中从偏移量的位置开始赋值,在 getter 方法中从偏移量开始取值,为了能够读取正确字节数,系统对象偏移量的指针类型进行了类型强转。


  • readwrite,readonly,assign,retain,copy,nonatomic,atomic,strong,weak属性的作用分别是什么。

关键字 注释
readwrite 此标记说明属性会被当成读写的,这也是默认属性。
readonly 此标记说明属性只可以读,也就是不能设置,可以获取。
assign 不会使引用计数加1,也就是直接赋值。
retain 会使引用计数加1。
copy 建立一个索引计数为1的对象,在赋值时使用传入值的一份拷贝。
nonatomic 非原子性访问,多线程并发访问会提高性能。
atomic 原子性访问。
**strong ** 打开ARC时才会使用,相当于retain
weak 打开ARC时才会使用,相当于assign,可以把对应的指针变量置为nil。


  • 什么情况使用 weak 关键字,相比 assign 有什么不同?
    首先明白什么情况使用 weak 关键字
    在 ARC 中,在有可能出现循环引用的时候,往往要通过让其中一端使用 weak 来解决,比如:

delegate 代理属性,代理属性也可使用
assign自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用 weak
自定义IBOutlet 控件属性一般也使用weak;当然,也可以使用 strong,但是建议使用 weak

  • weak 和 assign 的不同点:

weak 策略在属性所指的对象遭到摧毁时,系统会将 weak 修饰的属性对象的指针指向 nil,在 OC 给 nil 发消息是不会有什么问题的;如果使用 assign 策略在属性所指的对象遭到摧毁时,属性对象指针还指向原来的对象,由于对象已经被销毁,这时候就产生了野指针,如果这时候在给此对象发送消息,很容造成程序奔溃assigin 可以用于修饰非 OC 对象,而 weak必须用于 OC 对象。


  • @synthesize 和 @dynamic 分别有什么作用
  • @property 有两个对应的词,一个是@synthesize,一个是@dynamic。
    如果@synthesize 和@dynamic 都没写,那么默认的就是
    @syntheszie var = _var;
  • @synthesize 的语义是如果你没有手动实现 setter 方法和 getter 方法,那么编译器会自动为你加上这两个方法。
    *@dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。(当然对于 readonly 的属性只需提供 getter 即可)假如一个属性被声明为@dynamic var;然后你没有提供@setter 方法和@getter 方法,编译的时候没问题,但是当程序运行到 instance.var = someVar,由于缺 setter方法会导致程序崩溃; 或者当运行到 someVar = instance.var 时,由于缺 getter 方法同样会导致崩溃。
    编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定.

copy 关键字

  • NSString、NSArray、NSDictionary 等等经常使用 copy 关键字,是因为他们有对应的可变类型NSMutableString、NSMutableArray、NSMutableDictionary.(不过我们一般对NSString用copy修饰
  • 为确保对象中的属性值不会无意间变动,应该在设置新属性值时拷贝一份,保护其封装性block,也经常使用 copy,关键字block。
  • 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区.
  • 在 ARC 中写不写都行:对于 block 使用 copy 还是 strong 效果是一样的,但是建议写上 copy,因为这样显示告知调用者“编译器会自动对 block 进行了 copy 操作。
  • 用@property 声明的 NSString(或NSArray,NSDictionary)经常使用 copy 关键字,为什么?如果改用 strong 关键字,可能造成什么问题?
    因为父类指针可以指向子类对象,使用 copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本.
    如果我们使用是 strong,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性.

关键字                            注释
浅复制(shallow copy)    在浅复制操作时,对于被复制对象的每一层都是指针复制。
深复制(one-level-deep copy)  在深复制操作时,对于被复制对象,至少有一层是深复制。
完全复制(real-deep copy)     在完全复制操作时,对于被复制对象的每一层都是对象复制。

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

推荐阅读更多精彩内容

  • 重点掌握 3 类对象和方法 对象就是一个物体 类的独特存在就是一个实例,对实例进行操作叫做方法。方法可以应用于类或...
    Coder大雄阅读 1,253评论 0 2
  • 红尘陌上,独自行走 绿萝拂过衣襟 青云打湿诺言 山和水可以两两相忘 日与月可以毫无瓜葛 那时候 只一个人的浮世清欢...
    骆驼计划艺术阅读 301评论 0 0
  • 现代人最怕是寂寞,借助着科学技术的发展,社交软件盛行于世,朋友圈不限时空在膨胀和延伸,在手机上聊几句成为了生活的...
    平仑阅读 132评论 0 0
  • 2017年12月11日 周一 阴 01 近来,总是为母亲的病情所扰,电话当然是要多打的,10月底还特意请假回去看了...
    慢世人阅读 152评论 0 0