gpt4 book ai didi

objective-c - 我可以覆盖 setValue : forKey:?

转载 作者:搜寻专家 更新时间:2023-10-30 19:57:49 27 4
gpt4 key购买 nike

我有一个对象可能将 NSNull 设置为其所有属性的值,而我正在使用的代码不能很好地处理 NSNull 值。是否可以像这样在我的对象中覆盖 setValue: forKey:?

-(void)setValue:(id)value forKey:(NSString *)key {

if ([value isEqual:[NSNull null]]) {
[super setValue:nil forKey:key];
} else {
[super setValue:value forKey:key];
}
}

object.property = [NSNull null] 被设置时,该方法不会被调用。我怎样才能使它成为我的 setter 的默认行为?

最佳答案

肯定有办法做到这一点。您可以声明相关属性 @dynamic,然后使用 +resolveInstanceMethod: 实际按需创建 setter。您可以在 sample code for 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 而不是在运行时执行此操作(它是一个线法)。我使用运行时的唯一原因是如果有一堆属性,并且对象非常简单(纯粹是一个数据对象)。

关于objective-c - 我可以覆盖 setValue : forKey:?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18370653/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com