Objective-C const常量的优雅使用方法

 更新时间:2022年08月08日 11:36:09   作者:小橘爷  
这篇文章主要为大家介绍了Objective-C const常量的优雅使用方法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

在编写代码时经常要使用常量,来替代 magic number。比较简单的做法是通过预处理指令 #define 来实现。

#define ANIMATION_DURATION 0.3 

上述预处理指令会在编译时的预处理阶段会将代码中 ANIMATION_DURATION 字符串替换为 0.3。这种定义常量的方式比较简便,但是存在两个问题:

  • 丢失了类型信息。
  • 若该预处理指令声明在头文件中,引入该头文件的代码,ANIMATION_DURATION 都会被替换,可能出现冲突。

Objective-C 的常量声明方式

幸运的是,Objective-C 中提供了 const 关键字,可以用来定义常量。const 关键字可以对变量加以限定,使其值不能被改变,在整个作用域中都保持固定。

const NSTimeInterval kAnimationDuration = 0.3;

这种方式定义的常量包含类型信息,且在编译时即可检查是否与其他常量出现冲突。如果试图修改由 const 修饰符所声明的变量,那么编译器就会报错。

如果常量仅在某个实现文件中使用,还应该加上 static 关键字,否则会被视为全局常量。若不使用 static,编译器会为它创建一个外部符号,若另一个编译单元中也声明了同名变量,就会报错。

static const NSTimeInterval kAnimationDuration = 0.3;

当一个变量同时使用了 staticconst,那么编译器并不会创建符号,而是会像 #define 预处理指令一样,把所有遇到的变量替换为常值。

有时候需要把一个常量暴露给外界使用,比如通知,此类常量需放在全局符号表中。可以使用 extern 关键字,在头文件中进行声明:

// .h
extern NSString * const AFNetworkingTaskDidResumeNotification;
// .m
NSString * const AFNetworkingTaskDidResumeNotification = @"com.alamofire.networking.task.resume";

该常量在头文件中声明,在实现文件中定义。需要注意的是 const 写在指针类型的右边意味着该指针的指向不可被改变,若写在左边意味着该指针指向的内容不可被改变。

按上述方式实现并定义后,在编译时生成目标文件时,编译器会在数据段为字符串分配存储空间。

Foundation 框架中,苹果为了兼容 C++ 中对 extern 的使用,提供了宏:

#if defined(__cplusplus)
#define FOUNDATION_EXTERN extern "C"
#else
#define FOUNDATION_EXTERN extern
#endif
#define FOUNDATION_EXPORT FOUNDATION_EXTERN
#define FOUNDATION_IMPORT FOUNDATION_EXTERN

一个 C++ 程序中可能包含其他语言编写的部分代码,同样,C++ 编写的代码片段也可能被用在其他语言编写的代码中。但是,不同语言编写的代码相互调用是困难的,更何况用同一种语言编写,使用不同编译器进行编译的情况。因为,不同语言或者同种语言在不同编译器上编译时,在注册变量,传递参数和参数在栈上的布局上可能存在差异。

为了使它们遵守统一规则,可以使用 extern 指定一个编译和链接规约。extern "C" 指令中的 C,表示的是一种编译和链接规约,而不是一种语言。C 表示符合 C 语言的编译和链接规约的任何语言。

还要说明的是,extern "C" 指令指定的编译和链接规约,不会影响语义,只是改变编译和链接的方式。

FOUNDATION_EXPORTFOUNDATION_IMPORT 是用来兼容 Win32 应用程序的,移动端开发可以忽略。

所以上述对全局常量的声明,可以写成:

// .h
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidResumeNotification;
// .m
NSString * const AFNetworkingTaskDidResumeNotification = @"com.alamofire.networking.task.resume";

在 Objective-C 中使用 let 来声明常量

使用过 Swift 的同学,一定对其声明常量的方式的简洁性印象深刻,在 Swift 中声明常量的方式如下所示:

let kAnimationDuration = 0.3

之所以能如此简洁,是因为 Swift 具有 let 关键字和类型推断的能力,但其实在 Objective-C 中也可以通过类似的方式来书写常量。

Objective-C 中有一个关键字,是 __auto_type,可以实现类似 Swift 中类型推断能力的关键字,如下所示:

const __auto_type kAnimationDuration = 0.3;

可能对于简单的数据类型,这样的优势不是很明显,但是对于具有复杂泛型的类型来说,可以说优势很大了:

// 旧方式
NSArray<NSDictionary<NSString *, NSString *> *> *models = ...;
// 新方式
__auto_type models = ...;

同时,可以通过宏的方式,来减少 __auto_type 的书写,即可实现通过 let 声明常量,var 声明变量。其中 auto 关键字是为了兼容 C++。

#if defined(__cplusplus)
#define let auto const
#else
#define let const __auto_type
#endif
#if defined(__cplusplus)
#define var auto
#else
#define var __auto_type
#endif

声明了上面的宏之后,就可以直接使用了:

let kAnimationDuration = 0.3;

以上就是Objective-C const常量的优雅使用方法的详细内容,更多关于Objective-C const常量的资料请关注脚本之家其它相关文章!

相关文章

  • 详解iOS应用开发中Core Data数据存储的使用

    详解iOS应用开发中Core Data数据存储的使用

    这篇文章主要介绍了iOS应用开发中Core Data数据存储的使用,Core Data可以看作是一个内嵌型数据库SQLite的iOS专用版本,需要的朋友可以参考下
    2016-02-02
  • IOS在SwiftUI中显示模态视图的实例代码

    IOS在SwiftUI中显示模态视图的实例代码

    这篇文章主要介绍了IOS在SwiftUI中显示模态视图的实例代码,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • iOS的CoreAnimation开发框架中的Layer层动画制作解析

    iOS的CoreAnimation开发框架中的Layer层动画制作解析

    在iOS中UIView层的属性会映射到CoreAnimation框架的CALayer,这里我们来看一下iOS的CoreAnimation开发框架中的Layer层动画制作解析,需要的朋友可以参考下
    2016-07-07
  • iOS开发之widget实现详解

    iOS开发之widget实现详解

    这篇文章主要为大家详细介绍了iOS开发之widget实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • iOS开发学习 ViewController使用示例详解

    iOS开发学习 ViewController使用示例详解

    这篇文章主要为大家介绍了iOS开发学习 ViewController使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • IOS property属性详细介绍使用注意事项

    IOS property属性详细介绍使用注意事项

    这篇文章主要介绍了IOS property属性详细介绍使用注意事项的相关资料,需要的朋友可以参考下
    2017-02-02
  • IOS 获取APP 版本号的实例详解

    IOS 获取APP 版本号的实例详解

    这篇文章主要介绍了IOS 获取APP 版本号的实例详解的相关资料,需要的朋友可以参考下
    2017-07-07
  • iOS项目的开发命名规范教程

    iOS项目的开发命名规范教程

    为了团队各成员之间代码的互通、可读、易维护性,特制订此开发规范。下面这篇文章主要给大家介绍了关于iOS项目的开发命名规范的相关资料,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-11-11
  • IOS 开发之查看大图的实现代码

    IOS 开发之查看大图的实现代码

    这篇文章主要介绍了IOS 开发之查看大图的实现代码的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
    2017-10-10
  • iOS判断网络请求超时的方法

    iOS判断网络请求超时的方法

    本篇文章主要介绍了iOS判断网络请求超时的方法,现在分享给大家,也给大家做个参考。感兴趣的小伙伴们可以参考一下。
    2016-12-12

最新评论