肯定有办法做到这一点。您可以声明相关属性@dynamic
,然后用于+resolveInstanceMethod:
按需实际创建设置器。您可以在iOS:PTL 的示例代码中找到这样的示例。这个例子演示了如何自动让你的访问器读取和写入字典 ( properties
) 而不是从 ivars。为了使这项工作适合您,您可能需要始终存储NSNull
在字典中并覆盖 getter ( propertyIMP()
) 以将其转换为nil
. 所以你会改变这个:
[[self properties] setValue:value forKey:key];
至:
[[self properties] setValue:(value ?: [NSNull null]) forKey:key];
并改变:
return [[self properties] valueForKey:NSStringFromSelector(_cmd)];
至:
id value = [[self properties] valueForKey:NSStringFromSelector(_cmd)];
return (value == [NSNull null] ? nil : value);
或类似的东西。
但是......除非这是一场重大胜利,否则我会避免这种魔法。我对此的典型解决方案是另辟蹊径,将它放在调用者不应该通过的[NSNull null]
时候。我使用如下函数RNNonNull()
:
id RNNonNull(id x) { return (x == [NSNull null]) ? nil : x; }
然后调用者负责添加包装器:
obj.foo = RNNonNull(mystuff);
如果那不可能,我可能会手动覆盖 getter 以转换NSNull
为nil
而不是使用运行时进行转换(这将是一种单行方法)。我使用运行时的唯一原因是如果有一堆属性,并且对象非常简单(纯粹是一个数据对象)。