Objective-C中使用宏时如何区分setter与getter方法?
在Objective-C宏中区分属性的Setter与Getter操作
现有TestClass类,通过单例模式访问testProperty属性,当前使用宏TESTMacro直接指向该属性,需要在不重写属性setter/getter方法的前提下,让这个宏在赋值(setter)和取值(getter)时执行不同的额外逻辑。现有代码如下:
#define TESTMacro [TestClass shared].testProperty @interface TestClass:NSObject @property (nonatomic,strong)NSString* testProperty; + (TestClass*)shared; @end @implementation TestClass +(TestClass *)shared{ static TestClass *shared = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ shared = [[TestClass alloc] init]; }); return shared; } -(void)testUser{ TESTMacro = @"1"; // setter操作 NSString *result = TESTMacro;// getter操作 } @end
解决方案
利用GCC/Clang编译器的内置函数__builtin_assignable判断宏的使用场景(左值/右值),结合语句表达式在宏中嵌入不同逻辑。修改宏定义如下:
#define TESTMacro \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wgnu-statement-expression\"") \ ({ \ TestClass *_sharedInst = [TestClass shared]; \ if (__builtin_assignable(__typeof__(_sharedInst.testProperty), &_sharedInst.testProperty)) { \ // Setter专属逻辑,可在这里添加额外操作 NSLog(@"执行Setter额外逻辑,即将赋值"); \ _sharedInst.testProperty; \ } else { \ // Getter专属逻辑,可在这里添加额外操作 NSLog(@"执行Getter额外逻辑,即将取值"); \ _sharedInst.testProperty; \ } \ }) \ _Pragma("clang diagnostic pop")
说明
__builtin_assignable(type, expr):编译器内置函数,判断expr是否可被赋值为type类型的值,以此区分赋值(左值)和取值(右值)场景。- 语句表达式(
({ ... })):GCC/Clang扩展特性,允许在宏中嵌入多语句逻辑,并返回最后一条语句的结果。 _Pragma指令:临时关闭-Wgnu-statement-expression警告,避免编译器对语句表达式的语法提示。
修改后,执行原有代码时:
TESTMacro = @"1"会先触发Setter专属逻辑,再完成属性赋值。NSString *result = TESTMacro会先触发Getter专属逻辑,再获取属性值并赋值给result。
内容的提问来源于stack exchange,提问作者YYuan
相关产品推荐
相关产品推荐

