最近我遇到了这个用于创建单例实例的宏。
#if __has_feature(objc_arc) // ARC Version
#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \
\
+ (classname *)sharedInstance\
{\
static classname *shared##classname = nil;\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
shared##classname = [[self alloc] init];\
});\
return shared##classname;\
}
有人可以告诉我每行中反斜杠字符的用法是什么。它提供的优势是什么?
此处##字符的用途是什么?
答案 0 :(得分:4)
在每行的末尾转义换行符,并允许像这样的复杂宏来保持可读性。
C预处理器宏必须在一行上定义(即由换行符终止),因此需要长宏来使用反斜杠来转义中间换行符。
顺便说一下,你会在Makefile中看到类似的东西。
答案 1 :(得分:1)
##
字符为令牌串联,请参阅http://en.wikipedia.org/wiki/C_preprocessor上的详情。
简而言之,它接受两个参数(字符串shared
和classname
的值)并从中生成一个字符串。
在这种情况下,您确实不需要使用##
,相同的宏可以使用以下内容:
#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \
\
+ (classname *)sharedInstance {\
static classname *singleton = nil;\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
singleton = [[self alloc] init];\
});\
return singleton;\
}
即使没有classname
参数,它也会正常工作:
#define SYNTHESIZE_SINGLETON \
\
+ (instancetype)sharedInstance {\
static id singleton = nil;\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
singleton = [[self alloc] init];\
});\
return singleton;\
}
请注意,缩进复杂的宏会有所帮助,因为它使它们更具可读性。