局部常量

在实现文件中使用 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. Catch That Cow POJ - 3278 [kuangbin带你飞]专题一 简单搜索

    Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. ...

  2. java-冒泡排序笔记

    //冒泡排序public class BubbleSort {    //    public static void main(String[] args) {//        // TODO 自 ...

  3. Java静态代码块、代码块及构造函数执行顺序

    根据以下程序进行分析 定义一个父类 package sas.LearnJava; public class ExcuteOrderTest { { System.out.println("我 ...

  4. InnoDB在MySQL默认隔离级别下解决幻读

    1.结论 在RR的隔离级别下,Innodb使用MVVC和next-key locks解决幻读,MVVC解决的是普通读(快照读)的幻读,next-key locks解决的是当前读情况下的幻读. 2.幻读 ...

  5. IOS集成JPush

    本篇文章采用Xcode手动集成JPush 证书 参考网址:https://docs.jiguang.cn//jpush/client/iOS/ios_cer_guide/ 下载SDK 下载网址:htt ...

  6. 安卓APP开发简单实例 结对编程心得

    开始说起搞APP开发,自己和小伙伴的编程水平真的很低,无从下手,只有在网上找点案列,学习着怎样开发,结对编程还是面临着许多问题的,大家的水平有所差异和编程风格不同,我们用eclipse做了一个仿微信登 ...

  7. TestNG(六) 忽略测试

    package com.course.testng.suite; import org.testng.annotations.Test; public class IgnoreTest { @Test ...

  8. Jenkins把GitHub项目做成Docker镜像

    本文是<Jenkins流水线(pipeline)实战>系列的第三篇,前面已对Jenkins流水线有了基本认识,也试过从GitHub下载pipeline脚本并执行,今天的实战是编写一段pip ...

  9. Spring Cloud异步场景分布式事务怎样做?试试RocketMQ

    一.背景 在微服务架构中,我们常常使用异步化的手段来提升系统的 吞吐量 和 解耦 上下游,而构建异步架构最常用的手段就是使用 消息队列(MQ),那异步架构怎样才能实现数据一致性呢?本文主要介绍如何使用 ...

  10. 给Xshell增加快速命令集

    一.显示快速命令栏 二.配置快速命令集 在工具中找到快速命令集 添加快速命令集 三.使用快速命令集