52个有效方法(4) - 多用类型常量,少用#define预处理指令
局部常量
在实现文件中使用 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只是简单的替换,又称作宏定义、预处理命令。extern与const联合使用时,const是要分配内存空间的,提示编译器遇到此变量和函数时在其他模块中寻找其定义#define是不会对数据类型进行检查extern与const联合使用时,是会对数据类型进行安全检查在shared libraries的情况下,
#define(相当于使用@""写法的“字面量”)不能保证得到的字符串地址是一样的。如果用@""的字符串作为dictionary的key的话,会导致它需要做isEqualToString的比较在
shared libraries的情况下,用extern NSString * const,只要做指针的比较。显然指针比较比逐个字符比较快多了。
@""写法的字符串会在编译期被替换成NSConstantString的实例,NSString也是唯一一种可以在编译期被实例化的类
要点
不要用预处理指令定义常量。这样定义出来的常量不含类型信息,编译器只会在编译前据此执行查找与替换操作。即使有人重新定义了常量值,编译器也不会产生警告信息,这将导致应用程序中的常量值不一致。
在实现文件中使用static const 来定义“只在编译单元内可见的常量”(translation-unit-specific constant)。一个编译单元就是一个.m文件。由于此常量不在全局符号表中,所以无需为其名称加前缀(在其前面加字母k)
在头文件中使用extern const来声明全局常量,并在相关实现文件中定义其值。这种常量要出现在全局符号表中,所以其名称应加以区分,通常用与之相关的类名做前缀。
52个有效方法(4) - 多用类型常量,少用#define预处理指令的更多相关文章
- Effective Objective-C 2.0 — 第四条:多用类型常量,少用#define预处理指令
第四条:多用类型常量,少用#define预处理指令 使用#define 预处理的坏处:定义出来的常量没有类型信息,编译器只是会在编译前据此执行查找与替换操作.即使有人重新定义了常量值,编译器也不会产生 ...
- 多用类型常量,少用#define预处理指令
摒弃: #define ANIMATION_DURATION 0.3 #define ERROR_MESSAGE @“ErrorMessage” 1)没有常量的类型信息 2)假设此指令声明在某个头 ...
- 第4条:多用类型常量,少用#define预处理指令
定义常量的几种方式: 1.#define ANIMATION_DURAION 0.3 //定义了一个动画时长的常量, 预处理过程会把碰到的所有ANIMATION_DURAION一律替换 ...
- iOS书摘之编写高质量iOS与OS X代码的52个有效方法
来自<Effective Objective-C 2.0编写高质量iOS与OS X代码的52个有效方法>一书的摘要总结 一.熟悉Objective-C 了解Objective-C语言的起源 ...
- 笔记 《Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法 》
阅读此书的笔记点: 此书目录即是对知识点最好的总结 第1章 熟悉Objective-C ---------------------------------------------- 第1条:了解Obj ...
- 第一章 熟悉Objective -C 编写高质量iOS与OS X代码的52 个有效方法
第一章 熟悉Objective -C 编写高质量iOS与OS X代码的52 个有效方法 第一条: 了解Objective-C 语言的起源 关键区别在于 :使用消息结构的语言,其运行时所应执行 ...
- 《编写高质量iOS与OS X代码的52个有效方法》书籍目录
一.熟悉Objective-C 1.了解Objective-C语言的起源 2.在类的头文件中尽量少引入其他头文件 3.多用字面量语法,少用与之等价的方法 4.多用类型常量,少用#define预处理指令 ...
- 编写高质量iOS与OS X代码的52个有效方法
第一章重点: 第一条:OC的起源 OC由smalltalk语言演化而来的语言为消息结构(messaging structure)语言,其运行时所因执行的的代码由运行环境来决定:函数调用(functio ...
- 【读书笔记】--《编写高质量iOS与OS X代码的52个有效方法》
1.Objective-C 起源: 在 C 语言基础上添加了面向对象特性,是 C 语言的超集.Objective-C 由 SmallTalk 语言演变过来,使用消息结构,运行环境由运行环境决定. OC ...
随机推荐
- 漫谈JavaScript中的提升机制(Hoisting)
前言 刚接触到JavaScript的时候,便知道JavaScript是按顺序执行的,是如浏览器的解析DOM树一样的流程,解析DOM结构的时候,如果遇到JS脚本或者外联脚本便会停止解析,继续下载脚本之后 ...
- centos 6.5 系统故障分析实验
系统故障分析实验 日志文件分析 日志的功能 用于记录系统.程序运行中发生的各种事件 通过阅读日志,有助于诊断和解决系统故障 日志文件的分类 内核及系统日志 由系统服务syslog统一进行管理,日志格式 ...
- Fire Balls 10——UI界面的制作
版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...
- C++ lambda的演化
翻译自https://www.bfilipek.com/2019/02/lambdas-story-part1.html与https://www.bfilipek.com/2019/02/lambda ...
- AutoCompleteTextView自动完成文本框
AutoCompleteTextView是从EditText派生出来的,比普通编辑框多了一个功能,当用户输入一定字符后,自动完成文本框会显示一个下拉单,供用户选择,当选中一个后,被选中的内容会显示在文 ...
- Redis是否安装
1.Redis对否安装(安装好了会出现下面对应的代码) [lk@localhost /]$ whereis redis-cli redis-cli: /usr/local/bin/redis-cli ...
- MapReduce应用案例
1 环境说明 注意:本实验是对前述实验的延续,如果直接点开始实验进入则需要按先前学习的方法启动hadoop 部署节点操作系统为CentOS,防火墙和SElinux禁用,创建了一个shiyanlou用户 ...
- django 中namespace的问题
在早期的django版本中 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^polls/', include('polls.urls' ...
- Qt无边框窗体-模拟模态窗体抖动效果
目录 一.概述 二.效果展示 三.功能实现 四.相关文章 原文链接:Qt无边框窗体-模拟模态窗体抖动效果 一.概述 用Qt开发windows客户端界面确实是一大利器,兼顾性能的同时,速度相对来说也不错 ...
- Day 21 进程管理
1.什么是进程 比如: 开发写的代码我们称为程序,那么将开发的代码运行起来.我们称为进程. 总结一句话就是: 当我们运行一个程序,那么我们将运行的程序叫进程. PS1: 当程序运行为进程后,系统会为该 ...