You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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")

说明

  1. __builtin_assignable(type, expr):编译器内置函数,判断expr是否可被赋值为type类型的值,以此区分赋值(左值)和取值(右值)场景。
  2. 语句表达式(({ ... })):GCC/Clang扩展特性,允许在宏中嵌入多语句逻辑,并返回最后一条语句的结果。
  3. _Pragma指令:临时关闭-Wgnu-statement-expression警告,避免编译器对语句表达式的语法提示。

修改后,执行原有代码时:

  • TESTMacro = @"1"会先触发Setter专属逻辑,再完成属性赋值。
  • NSString *result = TESTMacro会先触发Getter专属逻辑,再获取属性值并赋值给result。

内容的提问来源于stack exchange,提问作者YYuan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 08:35:40