考虑以下 setter :
- (void)setWinterStatusNSString *)status
{
NSLog(@"Variable update called");
if (_status != status)
{
[_status release];
_status = [status retain];
NSLog(@"Variable actually updated");
}
}
- (void)setCharacterStateEnumCharacterState)state
{
NSLog(@"Variable update called");
if (_state != state)
{
_state = state;
NSLog(@"Variable actually updated");
}
}
注意这些方法是相似的——它记录一条通用消息,检查它是否真的在改变,影响改变,如果改变了,就记录下来。如果我有足够的这样的方法,我可能想写一个包装器,这样我就可以简单地写:
- (void)setCharacterStateEnumCharacterState)state
{
[setValue(state) forSelectorselector(state)];
}
但我不确定这是否可能。我不能使用 KVO,因为似乎默认添加的 KVO 代码实际上调用的是 setter,所以这样做会导致无休止的递归。我不知道如何从@selector(state)
获取instance变量,也不知道是否需要release/retain
。有什么办法吗?
注意:对象类型的基类必须保持NSObject
;我不能使用 NSManagedObject
作为基础来处理我自己的 KVO。
编辑:
所以显然有一种使用运行时 c 函数的方法(请参阅接受的答案);似乎可能需要一些时间才能正确,但我在此期间找到了另一个解决方案。我将自己注册为所有我想要“包装”的方法的观察者,观察 NSKeyValueObservingOptionNew
、NSKeyValueObservingOptionOld
和 NSKeyValueObservingOptionPrior
。然后在前面的处理程序中,我 NSLog(@"Variable update called")
,在更新处理程序中,我 NSLog(@"Variable 实际上更新了")
。这似乎运作良好
简答:可以,但不要。
长答案:
假设您出于教育原因想要这样做(而不是仅仅让编译器为您创建 setter,最近的编译器中的默认设置)这是可能的,但这并不重要。
您已经注意到一个区别——是否需要保留/释放(假设为 MRC)——但还有更多区别。例如,考虑简单的一行:
_state = state;
它有什么作用?复制一个字节?两个字节?八个字节?代码在不同的 setter 中可能看起来相同,但它会编译成不同的机器码。
然后属性上还有复制和弱属性要考虑...
还在考虑这样做吗?
您需要熟悉 void **
的含义,通过指针复制可变长度的数据等。然后看看 object_setInstanceVariable
,property_getAttributes
等 - 这些都是 C 函数,您可以在 Objective-C Runtime Reference 中找到它们.
从中您会发现您需要了解type encodings (这将帮助您确定要复制多少字节)等等......
玩得开心!
HTH
关于ios - 我可以实现一个属性 setter ,它通常调用另一个方法来执行设置吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28294838/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |