谈谈为何iOS开发别用宏来定义常量

 更新时间:2016年08月03日 18:10:49   投稿:daisy  
最近在工程里看到很多不规范的使用,于是来写一篇博客来让不是很清楚的小朋友们,使用正确的规范开发ios,少埋点坑。

首先,预处理命令他不是一个常量!!!!

我们来看一段代码

#define avatar @"60"
 if (false) {
  #define avatar @"80"
 }
 NSLog(avatar);

这段代码会输出多少,我们将“avatar”定义为了60,然后在一个永远不会执行的代码里面重新定义了“avatar”为80,if语句中的代码永远不会执行,但是在编译时期,编译器会编译这段代码,而这个时候编译器就会将avatar这个名字替换为@“80”,所以这段代码最后的输出结果就是80。

当然这个时候编译器是会有一个警告的,但是不知道有多少同学会忽略这个警告。或者你会告诉我你对警告十分敏感,不会放过他的,但是记住你不是一个人在写代码,可能在别人的页面他给你重新定义了你的define,给你挖了一个大坑,还找不着.........

用const来定义一个常量

const修饰符定义的变量是不可变的,比如说你需要定义一个动画时间的常量,你可以这么做:

static const NSTimeInterval kAnimateDuration = 0.3;

当你试图去修改“ kAnimateDuration”的值的时候,编译器会报错。更加重要的是用这种方法定义的常量是带有类型信息的,而这点则是define不具备的。

也许你已经发现了,如果你像这样定义:

static const NSString * kUserName = @"StrongX";

你是可以修改userName的值的,(说好的常量呢~~~)

首先我们需要确定的是以下两种写法是一样的:

static NSString const * kUserName = @"StrongX";
static const NSString * kUserName = @"StrongX";


也就是说const放在类型前还是类型后是一样的效果。然后不同效果的是下面这种写法:

static NSString * const kUserName = @"StrongX";

const 修饰的是他右边的部分,也就是说:

static NSString const * kUserName = static NSString const (* kUserName )

static NSString * const kUserName = static NSString * const (kUserName)

const修饰的是(userName)的时候,不可变的是userName;“*”在C语言中表示
指针指向符,也就是说这个时候userName指向的内存块地址不可变,而内存保存的内容是可变的,我们来做个尝试:

 NSLog(@"内存地址: %x",& kUserName);
 kUserName = @"superXLX";
 NSLog(@"内存地址: %x",& kUserName);

以上NSLog会打印*userName指向的内存块地址,而他的输出是:


输出

我们已经发现当我们改变内存的内存的时候他的地址并没有发生改变,也就是说这是符合“const”修饰符的规定的。

而当我们的修饰符是这样的时候:

static NSString * const kUserName = @"StrongX";

我们则无法改变userName的值。

所以当我们需要定义一个不可变的常量的时候 ,我们还是需要将“const”修饰符放到“*”指针指向符后边才对。

一定要同时使用static和const来定义你的变量

上面已经说了const是用来定义一个常量。而static在C语言中(OC中延用)则表明此变量只在改变量的输出文件中可用(.m文件),如果你不加“static”符号,那么编译器就会对该变量创建一个“外部符号”,后果是什么呢?
你可以尝试在不同编译文件中加入以下代码:

NSString * const kUserName = @"StrongX";

可能尽管文件之间并没有相互引用,不存在属性名重复的问题(因为这并不是一个属性,这是一个外部符号),但是编译器还是报错了:

他会告诉你在两个目标文件(.0文件是.m文件编译后的输出文件)有一个重复的符号。(OC中没有类似C++中的名字空间的概念)

所以当你在你自己的.m文件中需要声明一个只有你自己可见的局部变量(k开头)的变量的时候一定要同时使用“static”“const”两个符号。

定义工程中的全局变量

在我们的工程中一定会定义很多全局常量,很多人的做法是会创建一个“ constant.h”文件,在这个文件中用#define声明许多常量,然后将这个头文件引入“pch”文件中,不能说这么做不对,但是如同上面说的那样define可能被修改,当然在命名规范的情况下这种情况很少出现,并且这样做的效率很高。

然而苹果更推荐另外一种做法:"extern",这样做的优势是保持常量绝对不会被修改,并且一定初始化还带有类型信息。

我们在"constants.h"文件中,声明常量

extern NSString *const XUserName;

然后在“constants.m”中定义他:

NSString *const XUserName = @"StrongX";

“extern”定义的常量必须也只能初始化一次,不满足必须以及只能一次的条件那么编译器就会提醒你。在定义全局变量的时候需要要注意你的命名,你可以使用规定好的前缀来命名。

“define”“extern”各有各的优势,不过我个人还是比较推荐使用“extern”.(因为之前在一个工程中被define坑惨了!)。

以上就是本文的全部内容,希望本文提到的知识点对大家开发IOS时有所帮助,让大家都能使用正确的规范开发IOS。

相关文章

  • 详解iOS应用中播放本地视频以及选取本地音频的组件用法

    详解iOS应用中播放本地视频以及选取本地音频的组件用法

    这里来为大家详解iOS应用中播放本地视频以及选取本地音频的组件用法,分别使用MPMoviePlayerControlle和MPMediaPickerController来实现,两个都是MediaPlayer.framework中的多媒体组件,所以我们放到一起来讲.
    2016-06-06
  • iOS 隐藏tabbar代码详解

    iOS 隐藏tabbar代码详解

    这篇文章主要介绍了iOS 隐藏tabbar代码详解的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • ios之UIScrollerView滚动视图总结

    ios之UIScrollerView滚动视图总结

    本篇文章主要介绍了ios之UIScrollerView滚动视图总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • IOS多线程编程的3种实现方法

    IOS多线程编程的3种实现方法

    这篇文章主要介绍了IOS多线程编程的3种实现方法的相关资料,需要的朋友可以参考下
    2015-11-11
  • iOS组件化开发实战记录

    iOS组件化开发实战记录

    这篇文章主要给大家介绍了关于iOS组件化开发的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-02-02
  • 3分钟实现iOS语言本地化/国际化(图文教程)

    3分钟实现iOS语言本地化/国际化(图文教程)

    这篇文章主要介绍了3分钟实现iOS语言本地化/国际化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • IOS ObjectiveC中的赋值与对象拷贝

    IOS ObjectiveC中的赋值与对象拷贝

    这篇文章主要介绍了IOS ObjectiveC中的赋值与对象拷贝的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下
    2017-09-09
  • 详解iOS开发中Keychain的相关使用

    详解iOS开发中Keychain的相关使用

    这篇文章主要介绍了iOS开发中Keychain的相关使用,文中列举了一个使用Keychain来保存密码的例子,需要的朋友可以参考下
    2015-10-10
  • iOS开发之UIScrollView控件详解

    iOS开发之UIScrollView控件详解

    UIScrollView是一个非常重要的控件,其可以展示比设备屏幕更大区域的内容,我们可以通过手指滑动来查看内容视图的每一部分内容,也可以通过手指捏合来对内容视图进行缩放操作,我们每天开发中都不断显式或隐式地与UIScrollView打交道,下面给大家详细介绍UIScrollView控件。
    2016-09-09
  • iOS开发中使用UIScrollView实现无限循环的图片浏览器

    iOS开发中使用UIScrollView实现无限循环的图片浏览器

    这篇文章主要介绍了iOS开发中使用UIScrollView实现无限循环的图片浏览器的方法,感兴趣的小伙伴们可以参考一下
    2016-03-03

最新评论