经常用 NSAssert
的同学会发现如下现象:通过 Xcode
创建工程会默认在 Release
模式关闭 NSAssert
。
为了方便避免歧义,后续
Release
模式统一用Configuration-Release
场景代替
本篇文章会简单介绍 Xcode
的内部工作方式,并提供一种让Xcode
在 Configuration-Release
场景 下 默认开启NSAssert
的方案。
Xcode
的内部工作方式
1、Demo 工程
如下所示,当开发者创建新的工程时 ,Xcode
会创建 ssxxss.xcodeproj/project.pbxproj
文件:
ssxxss.xcodeproj/project.pbxproj
文件会有如下配置:
Xcode 的 Build Settings
页面显示如下:
- <span
Configuration-Release
场景,ENABLE_NS_ASSERTIONS = YES
。 - <span
Configuration-Release
场景,ENABLE_NS_ASSERTIONS = NO
。
2、默认配置文件
实际上,上面的配置来源是 Xcode
的 TemplateInfo.plist
模板文件:
/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/Project Templates/Base/Base_ProjectSettings.xctemplate/TemplateInfo.plist
如下,TemplateInfo.plist
存在一个默认的配置,在Project Configurations Release
路径下,存在默认的配置项:
ENABLE_NS_ASSERTIONS = NO
该配置项的含义是:
- <span
Configuration-Release
场景 下,增加配置项ENABLE_NS_ASSERTIONS = NO
2、Clang LLVM 1.0.xcspec
当构建系统 (BuildSystem)运行时,Xcode 会读取下面路径的配置文件:
代码语言:javascript复制/Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins/Clang LLVM 1.0.xcplugin/Contents/Resources/Clang LLVM 1.0.xcspec
如下,Clang LLVM 1.0.xcspec
存在如下与NS_BLOCK_ASSERTIONS
相关的配置:
该配置的含义是:1、 在 预处理阶段Preprocessing
,对于文件类型 sourcecode.c.objc
和 sourcecode.cpp.objcpp
,增加新的命令行参数。2、默认的命令行参数是 空字符串3、当 Configuration-*
场景存在 ENABLE_NS_ASSERTIONS = NO
的配置时,命令行参数是 -DNS_BLOCK_ASSERTIONS=1
3、NSAssert
在 SDK
的头文件中,NSAssert
会通过宏判断 NS_BLOCK_ASSERTIONS
是否被定义。如果定义不存在,会将 NSAssert
重写为真正的断言处理逻辑否则,会重写为空逻辑do {} while (0)
通过 Xcode
创建工程会默认在 Release
模式关闭 NSAssert
通过对 Xcode 工作原理的简单讲解,我们可以猜测修改TemplateInfo.plist
模板文件后,就可以实现本文的目录。
1、修改配置文件
代码语言:javascript复制/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/Project Templates/Base/Base_ProjectSettings.xctemplate/TemplateInfo.plist
2、验证
新建工程后,打开 Xcode 的 Build Settings
页面:
- <span
Configuration-Release
场景,ENABLE_NS_ASSERTIONS = YES
。 - <span
Configuration-Release
场景,ENABLE_NS_ASSERTIONS = YES
。
总结
本篇文章通过简单介绍 Xcode
的内部工作方式,并提供一种让Xcode
在 Configuration-Release
场景 下 默认开启NSAssert
的方案。