iOS开发深入了解宏定义#define

关于宏定义相信大家一定不会陌生,我们经常使用的都是一些简单的宏定义常量,或者使用宏定义一个方法。但是在项目中会使用到很多你真的理解宏定义的语法吗?
下面来展示一些宏定义的用法:
1.使用宏定义定义一个常量

//This defines PI
#define M_PI        3.14159265358979323846264338327950288

2.使用宏定义定义一个func

//this define a MIN()
#define MIN(A,B) (A<B?A:B)

这些对大家来说可能都是很常见的,但是#define的高级用法在下面。
3.宏定义的嵌套

#define USER_GLOBAL(obj, userType)   _USER_CORE(obj, @#userType, nil)
#define _USER_CORE(obj, strType, strGroup)                      [AppUser apply:obj withUserType:strType withGroup:strGroup]

使用简单的宏替代很长的方法,实现参数的传递
ps:@# 是字符化操作符,将传入的单字符操作名转化为字符


下面详细解释一下宏定义中的#、##、@#、\操作符的使用
“#”:字符串化操作符,作用是:将宏定义中的传入参数名转换成用一对双引号括起来参数名字符串。使用条件:只能用于有传入参数的宏定义中,且必须置于宏定义体中的参数名前
举例:

#define example1(instr) #instr
string str=example1(abc); 将会展成:string str="abc";
注意:对空格的处理
a、忽略传入参数名前面和后面的空格。
如:str=example1(   abc ); 将会被扩展成 str="abc";
b、当传入参数名间存在空格时,编译器将会自动连接各个子字符串,用每个子字符串中只以一个空格连接,忽略其中多余一个的空格。
如:str=exapme1( abc    def); 将会被扩展成 str="abc def"

“##”: 符号连接操作符,作用:将宏定义的多个形参名连接成一个实际参数名,使用条件:只能用于有传入参数的宏定义中,且必须置于宏定义体中的参数名前

#define exampleNum(n) num##n
int num=exampleNum(9); 将会扩展成 int num=num9;
注意:
1、当用##连接形参时,##前后的空格可有可无。
如:#define exampleNum(n) num ## n 相当于 #define exampleNum(n) num##n
2、连接后的实际参数名,必须为实际存在的参数名或是编译器已知的宏定义

@#:名称:字符化操作符 作用:将传入的单字符参数名转换成字符,以一对单引用括起来。使用条件:只能用于有传入参数的宏定义中,且必须置于宏定义体中的参数名前。

举例:

#define makechar(x) @#X
a = makechar(b); 展开后变成了:a= 'b';

\ : 行继续操作符 作用:当定义的宏不能用一行表达完整时,可以用”\”表示下一行继续此宏的定义。注意:换行不能切断单词,只能在空格的地方进行。


3.使用宏定义定义方法

/** 添加一个函数声明 */
#define _DEFINE_DATA_FUNC_INTERNAL(name, dataType)  \
                             -(void)set##name:(dataType)value; \
                             -(dataType)get##name; \
                             +(NSString *)key##name; \
                             -(BOOL)has##name;

4.使用宏定义定义方法实现

/** 添加一个函数定义 */
#define _IMPLEMENT_DATA_FUNC_INTERNAL(name, dataType, funForType, strKey) \
                -(void)set##name:(dataType)value { \
                [self set##funForType:value forKey:strKey]; \
                 } \
                -(dataType)get##name { \
                  return [self get##funForType:strKey]; \
                 } \
                +(NSString *)key##name { \
                  return strKey; \
                 }\
                -(BOOL)has##name {\
                  return [self hasKey:strKey]; \
                 }

5.使用宏定义创建单例类

#define GTMOBJECT_SINGLETON_BOILERPLATE(_object_name_, _shared_obj_name_)                                            \
__strong static _object_name_ *z##_shared_obj_name_ = nil;   \
+ (_object_name_ *)_shared_obj_name_ {                       \
    static dispatch_once_t pred = 0;                        \
    dispatch_once(&pred, ^{                                  \
        z##_shared_obj_name_ = [[self alloc] init];          \
    });                                                      \
    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_;                             \
}                                                            \
- (id)copyWithZone:(NSZone *)zone {                          \
    return self;                                             \
}                                                            \
+ (void)destroy##_object_name_ {                             \
}

参考链接:http://blog.csdn.net/zhubosa/article/details/51276652

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#ifndef MYSPDLOG_H #define MYSPDLOG_H #include <fstream> #include <iostream> #define SPDLOG_HEADER_ONLY #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG #include "spdlog/spdlog.h" #include "spdlog/logger.h" #include "spdlog/sinks/basic_file_sink.h" #include "spdlog/sinks/rotating_file_sink.h" #include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/sinks/daily_file_sink.h" class MySpdlog { public: static MySpdlog*getInstace() { static MySpdlog MySpdlogStatic; return &MySpdlogStatic; } int init() { std::string formatStr="%Y-%m-%dT%H:%M:%S.%e[%l][%s:%#][%!]%v"; // auto myLogger1 = std::make_sharedspdlog::sinks::rotating_file_sink_mt("spdlog", "logs/myspdlog.log", 1024 * 1024 * 10, 10); // auto myLogger1 = std::make_sharedspdlog::sinks::daily_file_sink("spdlog", "logs/log.txt", 0, 0); auto myLogger1 = spdlog::daily_logger_mt("spdlog", "logs/log.txt", 0, 0); // myLogger1 = spdlog::rotating_logger_mt("spdlog", "logs/myspdlog.log", 1024 * 1024 * 10, 10); spdlog::set_default_logger(myLogger1); myLogger1->set_level(spdlog::level::debug); myLogger1->set_pattern(formatStr); myLogger2 = spdlog::stdout_color_mt("baseLogger2"); spdlog::set_default_logger(myLogger2); myLogger2->set_level(spdlog::level::debug); myLogger2->set_pattern(formatStr); return 0; } void uninit() { } static std::shared_ptrspdlog::logger myLogger1; static std::shared_ptrspdlog::logger myLogger2; private: MySpdlog() {} ~MySpdlog() {} }; std::shared_ptrspdlog::logger MySpdlog::myLogger1; std::shared_ptrspdlog::logger MySpdlog::myLogger2; #define SPLOG_INIT() MySpdlog::getInstace()->init() #define SPLOG_UNINIT() MySpdlog::getInstace()->uninit() #define SPLOG_DEBUG(...) do {SPDLOG_LOGGER_DEBUG(MySpdlog::myLogger1, VA_ARGS);\ SPDLOG_LOGGER_DEBUG(MySpdlog::myLogger2, VA_ARGS);}while(0) #define SPLOG_INFO(...) do {SPDLOG_LOGGER_INFO(MySpdlog::myLogger1, VA_ARGS);\ SPDLOG_LOGGER_INFO(MySpdlog::myLogger2, VA_ARGS);}while(0) #define SPLOG_ERROR(...) do {SPDLOG_LOGGER_ERROR(MySpdlog::myLogger1, VA_ARGS);\ SPDLOG_LOGGER_ERROR(MySpdlog::myLogger2, VA_ARGS);}while(0) #define SPDLOG_CLRAR(a) do{std::fstream fout((a),std::ios::out|std::ios::trunc);fout.close();}while(0); #endif // MYSPDLOG_H这样写完编译后报错:-1: error: main.o:(.bss+0x10): multiple definition of `MySpdlog::myLogger2'; csocketfactory.o:(.bss+0x10): first defined here
06-13

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值