局部常量

在实现文件中使用 static const 来定义“只在编译单元内可见的常量”(translation-unit-specific constant)。其命名规则为在前面加字母k

//
// EOCAnimatedView.h
// #import <UIKit/UIKit.h> @interface EOCAnimatedView : UIView @end //
// EOCAnimatedView.m
// #import "EOCAnimatedView.h" static const NSTimeInterval kAnimataionDuataion = 0.5;
@implementation EOCAnimatedView @end
  • static const 与 #define

    • 编译时刻:#define是预编译(编译之前处理),const是编译阶段。

    • 编译检查:#define不做检查,不会报编译错误,只是替换,const会编译检查,会报编译错误。

    • #define的好处:#define能定义一些函数,方法。 const不能。

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

    • 在确定了使用的常量类型,及常量值时使用 const 进行定义;而简单的函数,或传参字符串等高级定义时,则使用#define进行宏定义。

全局常量

在头文件中使用extern const 来声明全局常量,并在相关实现文件中定义其值。其命名规则为以类名为前缀。

//
// EOCAnimatedView.h
// #import <UIKit/UIKit.h> extern NSString *const EOCAnimatedViewStringConstant;
extern const NSTimeInterval EOCAnimatedViewDuration; @interface EOCAnimatedView : UIView @end //
// EOCAnimatedView.m
// #import "EOCAnimatedView.h" NSString *const EOCAnimatedViewStringConstant = @"VALUE";
const NSTimeInterval EOCAnimatedViewDuration = 3.3; @implementation EOCAnimatedView @end

这个常量在头文件中"声明",且在实现文件中"定义".

注意const修饰符的位置,常量定义应该从右至左解读,所以在示例中, EOCAnimatedViewStringConstant就是"一个常量, 而这个常量是指针, 指向NSString对象".这与需求是相符的,因为我们不希望有人改变此指针常量.使其指向另外一个NSString对象.

还要说一点就是因为符号要放在全局符号表中,所以一定要注意常量的命名规范.避免名称冲突,最好使用与之相关的类名做前缀.系统框架中一般都是这么做的.

  • extern const 与 #define

  • #define只是简单的替换,又称作宏定义、预处理命令。

  • externconst联合使用时,const是要分配内存空间的,提示编译器遇到此变量和函数时在其他模块中寻找其定义

  • #define是不会对数据类型进行检查

  • externconst联合使用时,是会对数据类型进行安全检查

  • 在shared libraries的情况下,#define(相当于使用@""写法的“字面量”)不能保证得到的字符串地址是一样的。如果用@""的字符串作为dictionarykey的话,会导致它需要做isEqualToString的比较

  • shared libraries的情况下,用extern NSString * const,只要做指针的比较。显然指针比较比逐个字符比较快多了。

@""写法的字符串会在编译期被替换成NSConstantString的实例,NSString也是唯一一种可以在编译期被实例化的类

要点

  1. 不要用预处理指令定义常量。这样定义出来的常量不含类型信息,编译器只会在编译前据此执行查找与替换操作。即使有人重新定义了常量值,编译器也不会产生警告信息,这将导致应用程序中的常量值不一致。

  2. 在实现文件中使用static const 来定义“只在编译单元内可见的常量”(translation-unit-specific constant)。一个编译单元就是一个.m文件。由于此常量不在全局符号表中,所以无需为其名称加前缀(在其前面加字母k)

  3. 在头文件中使用extern const来声明全局常量,并在相关实现文件中定义其值。这种常量要出现在全局符号表中,所以其名称应加以区分,通常用与之相关的类名做前缀。

52个有效方法(4) - 多用类型常量,少用#define预处理指令的更多相关文章

  1. Effective Objective-C 2.0 — 第四条:多用类型常量,少用#define预处理指令

    第四条:多用类型常量,少用#define预处理指令 使用#define 预处理的坏处:定义出来的常量没有类型信息,编译器只是会在编译前据此执行查找与替换操作.即使有人重新定义了常量值,编译器也不会产生 ...

  2. 多用类型常量,少用#define预处理指令

    摒弃: #define ANIMATION_DURATION 0.3   #define ERROR_MESSAGE @“ErrorMessage” 1)没有常量的类型信息 2)假设此指令声明在某个头 ...

  3. 第4条:多用类型常量,少用#define预处理指令

    定义常量的几种方式: 1.#define ANIMATION_DURAION 0.3         //定义了一个动画时长的常量, 预处理过程会把碰到的所有ANIMATION_DURAION一律替换 ...

  4. iOS书摘之编写高质量iOS与OS X代码的52个有效方法

    来自<Effective Objective-C 2.0编写高质量iOS与OS X代码的52个有效方法>一书的摘要总结 一.熟悉Objective-C 了解Objective-C语言的起源 ...

  5. 笔记 《Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法 》

    阅读此书的笔记点: 此书目录即是对知识点最好的总结 第1章 熟悉Objective-C ---------------------------------------------- 第1条:了解Obj ...

  6. 第一章 熟悉Objective -C 编写高质量iOS与OS X代码的52 个有效方法

    第一章 熟悉Objective -C   编写高质量iOS与OS  X代码的52 个有效方法   第一条: 了解Objective-C 语言的起源 关键区别在于 :使用消息结构的语言,其运行时所应执行 ...

  7. 《编写高质量iOS与OS X代码的52个有效方法》书籍目录

    一.熟悉Objective-C 1.了解Objective-C语言的起源 2.在类的头文件中尽量少引入其他头文件 3.多用字面量语法,少用与之等价的方法 4.多用类型常量,少用#define预处理指令 ...

  8. 编写高质量iOS与OS X代码的52个有效方法

    第一章重点: 第一条:OC的起源 OC由smalltalk语言演化而来的语言为消息结构(messaging structure)语言,其运行时所因执行的的代码由运行环境来决定:函数调用(functio ...

  9. 【读书笔记】--《编写高质量iOS与OS X代码的52个有效方法》

    1.Objective-C 起源: 在 C 语言基础上添加了面向对象特性,是 C 语言的超集.Objective-C 由 SmallTalk 语言演变过来,使用消息结构,运行环境由运行环境决定. OC ...

随机推荐

  1. 洛谷 题解 P3871 【[TJOI2010]中位数】

    这题先定义一个大根堆(maxn)维护mid(n为奇数mid+1)的元素.再定义一个小根堆(minn)维护mid(n为奇数mid+1)到n的元素.然后对于插入元素的情况进行分类讨论. 当add x时 一 ...

  2. 题解 洛谷P1196 【[NOI2002]银河英雄传说】

    题意 有一个划分成n列的星际战场,各列编号为1,2.....n.有n艘战舰,也依次编号1,2.....n,其中第i号战舰位于第i列. 有m条指令,每条指令格式如下 M i j 表示让第i号战舰所在列的 ...

  3. 接口压测工具WRK的学习与使用

    之前一直在使用jmeter,第一次接触wrk,记录下使用过程以便自己再次使用. 首先,WRK是linux系统上才可以使用的工具,我也不想剑走偏锋的去研究如何让wrk可以在windows系统上使用. 临 ...

  4. Java代理设计模式(Proxy)的几种具体实现

    Proxy是一种结构设计模型,主要解决对象直接访问带来的问题,代理又分为静态代理和动态代理(JDK代理.CGLIB代理. 静态代理:又程序创建的代理类,或者特定的工具类,在平时开发中经常用到这种代理模 ...

  5. 结合生活案例实现rabbitmq消息通信

    title: 基于springboot实现rabbitmq消息通信 date: 2019-09-11 09:00:30 tags: - [rabbitmq] categories: - [spring ...

  6. WTM送书活动:向更遥远的星辰大海起航~

    是的,没错~ 这一篇不是大老刘写的.哈哈~ 啥?  你想知道为啥? 大老刘为了你们不加班,熬夜改BUG,姑娘不乐意了... 然后... 后面请自行脑补~ 哎~生活还要继续鸭.... 那么,接下来由我陪 ...

  7. Vuex,从入门到...

    Vuex 是什么? 官方是这么说的:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 不懂? ...

  8. Azure Application Insights REST API使用教程

    本文是Azure Application Insights REST API的简单介绍,并会包含一个通过Python消费API的示例/小工具. 新加入的team中的一项工作是制作日常的运维报表,制作方 ...

  9. log4j日志不输出的问题

    今天服务器上报错,想先去看一下日志进行排查,结果发现日志很久都没有输出过了.从上午排查到下午,刚刚解决,因此记录一下,但现在也只是知其然,并不知其所以然,所以如果大家有什么想法请在下方评论. 先说一下 ...

  10. 译 .NET Core 3.0 发布

    原文:<Announcing .NET Core 3.0> 宣布.NET Core 3.0 发布 很高兴宣布.NET Core 3.0的发布.它包括许多改进,包括添加Windows窗体和W ...