objective-c宏定义
1、先来几个常用的:
- // 是否高清屏
- #define isRetina ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 960), [[UIScreen mainScreen] currentMode].size) : NO)
- // 是否模拟器
- #define isSimulator (NSNotFound != [[[UIDevice currentDevice] model] rangeOfString:@"Simulator"].location)
- // 是否iPad
- #define isPad (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
- // 是否iPad
- #define someThing (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)? ipad: iphone
2、基本的使用:
- //定义π值 3.1415926
- #define PI 3.1415926
- //则在程序用可以如下使用
- double i=2*PI*3;
- //效果相当于 double i=2*3.1415926*3;
- //预处理命令可以定义任何符合格式的形式,例如判断年份是否闰年
- #define IS_LEAP_YEAR year%4==0&&year%100!=0||year%400==0
- //使用时则可以直接
- if(IS_LEAP_YEAR)
- //或者可以定义一个参数
- #define IS_LEAP_YEAR(y) y%4==0&&y%100!=0||y%400==0
- //使用时则可以直接
- int ys=2012;
- if(IS_LEAP_YEAR(ys))
- //通常预处理程序定义在一行 如果好分行 比如说太长需要换行 需要使用“/”符号 表示还有下一行,多行分列也是如此,例:
- #Define IS_LEAP_YEAR year%4==0&&year%100!=0/
- ||year%400==0
- //宏定义参数后边放一个# 那么在调用该宏时,预处理程序将根据宏参数创建C风格的常量字符串 例:
- #define STR(x) # x
- //将会使得 随后调用的
- NSLOG(STR(Programming in Objective-c./n));
- //显示结果为 Programming in Objective-c./n
3、关于#与##的操作符:
<1>.宏定义中字符串化操作符#:
#的功能是将其后面的宏参数进行字符串化操作,意思就是对它所应用的宏变量通过替换后在其左右各加上一个双引号。例如
- #define WARN_IF(EXPR)\
- do {\
- if (EXPR)\
- fprintf(stderr, "Warning: " #EXPR "\n");\
- } while(0)
- 上面代码中的反斜线\主要用来转译换行符,即屏蔽换行符。
- 那么如下的代码调用:
- WARN_IF(divider == 0);
- 将被解析为:
- do {\
- if (divider == 0)\
- fprintf(stderr, "Warning: " "divider == 0" "\n");\
- } while(0);
注意能够字符串化操作的必须是宏参数,不是随随便便的某个子串(token)都行的。
<2>.宏定义中的连接符##:
连接符##用来将两个token连接为一个token,但它不可以位于第一个token之前or最后一个token之后。注意这里连接的对象只要是token就行,而不一定是宏参数,但是##又必须位于宏定义中才有效,因其为编译期概念(比较绕)。
- #define LINK_MULTIPLE(a, b, c, d) a##_##b##_##c##_##d
- typedef struct _record_type LINK_MULTIPLE(name, company, position, salary);
- /*
- * 上面的代码将被替换为
- * typedef struct _record_type name_company_position_salary;
- */
- 又如下面的例子:
- #define PARSER(N) printf("token" #N " = %d\n", token##N)
- int token64 = 64;
- 如下调用宏:
- PARSER(64);
- 将被解析为:
- printf("token" "64" " = %d\n", token64);
- 在obj-c中,如果我有如下定义:
- #define _X(A, B) (A#B)
- #define _XX(A, B) _X([NSString stringWithFormat:@"%@_c", A], B)
- gcc将报错!
- 正确的写法为:
- #define _XX(A, B) _X(([NSString stringWithFormat:@"%@_c", A]), B)
4、再来个宏定义 object-c 单例
- #define GTMOBJECT_SINGLETON_BOILERPLATE(_object_name_, _shared_obj_name_)
- static _object_name_ *z##_shared_obj_name_ = nil;
- + (_object_name_ *)_shared_obj_name_ {
- @synchronized(self) {
- if (z##_shared_obj_name_ == nil) {
- /* Note that ‘self’ may not be the same as _object_name_ */
- /* first assignment done in allocWithZone but we must reassign in case init fails */
- z##_shared_obj_name_ = [[self alloc] init];
- _GTMDevAssert((z##_shared_obj_name_ != nil), @”didn’t catch singleton allocation”);
- }
- }
- return z##_shared_obj_name_;
- }
- + (id)allocWithZone:(NSZone *)zone {
- @synchronized(self) {
- if (z##_shared_obj_name_ == nil) {
- z##_shared_obj_name_ = [super allocWithZone:zone];
- return z##_shared_obj_name_;
- }
- }
- /* We can’t return the shared instance, because it’s been init’d */
- _GTMDevAssert(NO, @”use the singleton API, not alloc+init”);
- return nil;
- }
- - (id)retain {
- return self;
- }
- - (NSUInteger)retainCount {
- return NSUIntegerMax;
- }
- - (void)release {
- }
- - (id)autorelease {
- return self;
- }
- - (id)copyWithZone:(NSZone *)zone {
- return self;
- }
5、条件编译:
- #if !defined(FCDebug) || FCDebug == 0
- #define FCLOG(...) do {} while (0)
- #define FCLOGINFO(...) do {} while (0)
- #define FCLOGERROR(...) do {} while (0)
- #elif FCDebug == 1
- #define FCLOG(...) NSLog(__VA_ARGS__)
- #define FCLOGERROR(...) NSLog(__VA_ARGS__)
- #define FCLOGINFO(...) do {} while (0)
- #elif FCDebug > 1
- #define FCLOG(...) NSLog(__VA_ARGS__)
- #define FCLOGERROR(...) NSLog(__VA_ARGS__)
- #define FCLOGINFO(...) NSLog(__VA_ARGS__)
- #endif
6、参照C语言的预处理命令简介 :
#define 定义一个预处理宏
#undef 取消宏的定义
#include 包含文件命令
#include_next 与#include相似, 但它有着特殊的用途
#if 编译预处理中的条件命令, 相当于C语法中的if语句
#ifdef 判断某个宏是否被定义, 若已定义, 执行随后的语句
#ifndef 与#ifdef相反, 判断某个宏是否未被定义
#elif 若#if, #ifdef, #ifndef或前面的#elif条件不满足, 则执行#elif之后的语句, 相当于C语法中的else-if
#else 与#if, #ifdef, #ifndef对应, 若这些条件不满足, 则执行#else之后的语句, 相当于C语法中的else
#endif #if, #ifdef, #ifndef这些条件命令的结束标志.
defined 与#if, #elif配合使用, 判断某个宏是否被定义
#line 标志该语句所在的行号
# 将宏参数替代为以参数值为内容的字符窜常量
## 将两个相邻的标记(token)连接为一个单独的标记
#pragma 说明编译器信息#warning 显示编译警告信息
#error 显示编译错误信息
参考链接:http://www.uml.org.cn/c++/200902104.asp
如何联系我:【万里虎】www.bravetiger.cn 【QQ】3396726884 (咨询问题100元起,帮助解决问题500元起) 【博客】http://www.cnblogs.com/kenshinobiy/
objective-c宏定义相关推荐
- C++ #define(宏定义)的使用
C++ 宏定义 #define命令是C++语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本. 宏定义的一般形式 #define <宏名& ...
- 如何用C语言改变宏定义的大小,C语言中宏定义使用的小细节
C语言中宏定义使用的小细节 #pragma#pragma 预处理指令详解 在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#p ...
- c 宏定义用法#define
转自:https://blog.csdn.net/boring_wednesday/article/details/78756696 宏定义 语法 #define name Stuff #de ...
- C语言宏定义使用技巧
写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性等等.下面列举一些成熟软件中常用得宏定义...... 1,防止一个头文件被重复包含 #ifndef COMDEF_H ...
- 【C语言】07-预处理指令;-宏定义
预处理指令简介; 1,C在对源程序进行编译之前,会对一些特殊的预处理指令作解释,产生一个新的源程序,此过程叫做编译预处理.C在经过编译预处理之后才对新的源码进行通常的编译; 2,预处理以'#'开头,且 ...
- 巧用宏定义进行调试 (转)
巧用宏定义进行调试 在进行程序设计时,有时我们往往不希望借住于调试工具(如:gdb, vc),而以输出调试信息的方式进行调试时,我们就可以借住于强大的宏定义来进行调试. 一.在GCC下的定义方法 ...
- python用海伦公式求面积_用带参数的宏定义,通过海伦公式求三角形的面积
要求: 海伦公式: ,其中 ,a,b,c为三角形的三个边.定义两个带参数的宏,一个用来求p,另一个用来求s 题目分析: 首先,题目要求是通过输入三角形的三条边,输出三角形的面积.因为不是任意的三条边都 ...
- iOS 开发 高级:使用 宏定义macros (#,##,...,__VA_ARGS_)
一直以来用宏定义#define也就是定义一些简单的常量,至多也就是定义一个函数,很少关注宏定义的用法.直到看到这样的代码: [cpp] view plaincopy #define PLAYSOUND ...
- IOS,十六进制颜色和RGB颜色的宏定义
2019独角兽企业重金招聘Python工程师标准>>> 16进制颜色值宏定义. //调用NSString *str = model.Color; NSString *strColor ...
- 关于函数式宏定义的学习
题记:回头看看原本学过的知识,发现那些原本以为理解了的皮毛都突然让自己变得陌生.逐步学习,不懈努力. 测试题目时发现得出的结论与自己给出的不同,于是查阅资料,重新学习宏定义相关的文章.在C与C++编程 ...
最新文章
- MATLAB | matlab运行、下载链接及21个matlab基本图像调试代码
- Python面试题-朋友昨天去面试,这5个Python面试题都被考到了,太神奇了!
- 近似装箱问题(两种脱机算法实现)
- tcp的发送端一个小包就能打破对端的delay_ack么?
- python页面切换_Python+Selenium学习--窗口切换及操作元素
- RecyclerView(三)实现聊天窗口样式(Android 5.0 新特性)
- kubernetes+docker
- 微信H5支付(基于Java实现微信H5支付)
- #winhec# 开发人员刷屏看点 (视频)
- Flutter高性能,线程安全,App开发的未来
- Live2D和wallpaperEngine公用
- java高级类_Java私塾跟我学系列——JAVA篇 第五章 Java高级类特性
- 机器学习实战(十一)FP-growth算法
- 网页轮显幻灯片 php,图片轮显代码大全(JS幻灯片)
- python爬虫网络中断_python爬虫中断
- 遇到问题你的PIN不可用,请单击以重置和bitlocker恢复密匙
- XP纯净版光盘ISO镜像文件
- 苹果4s手机装 java微信_苹果4s微信版本过低怎么办 大师来详解
- 查询微信被谁投诉方法技巧
- Wangle中EchoClient分析
热门文章
- mysql 5.5 性能测试,MySQL 5.5迁移到5.7的性能问题排查案例
- 小米盒子显示gitv不动_2020电视盒子排行榜,五款“真香”盒子报到
- leetcode刷题:合并两个有序链表
- rdlc报表 矩形高固定_固定资产管理系统_简化资产管理流程
- java esc_java – Swing:当按下ESC键时如何关闭对话框?
- java中sort的cmp_快速排序(cmp函数详解)
- janusgraph整合mysql_图解图库JanusGraph系列-一文知晓“图数据“底层存储结构
- axis2生成客户端代码_利用ApiPost一键、快速生成接口文档!女猿也过38节!
- go语言 gosched
- TensorFlow tf.keras.layers.Dense