OStack程序员社区-中国程序员成长平台

标题: ios - 我可以实现一个属性 setter ,它通常调用另一个方法来执行设置吗? [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 05:13
标题: ios - 我可以实现一个属性 setter ,它通常调用另一个方法来执行设置吗?

考虑以下 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 函数的方法(请参阅接受的答案);似乎可能需要一些时间才能正确,但我在此期间找到了另一个解决方案。我将自己注册为所有我想要“包装”的方法的观察者,观察 NSKeyValueObservingOptionNewNSKeyValueObservingOptionOldNSKeyValueObservingOptionPrior。然后在前面的处理程序中,我 NSLog(@"Variable update called"),在更新处理程序中,我 NSLog(@"Variable 实际上更新了")。这似乎运作良好



Best Answer-推荐答案


简答:可以,但不要。

长答案:

假设您出于教育原因想要这样做(而不是仅仅让编译器为您创建 setter,最近的编译器中的默认设置)这是可能的,但这并不重要。

您已经注意到一个区别——是否需要保留/释放(假设为 MRC)——但还有更多区别。例如,考虑简单的一行:

_state = state;

它有什么作用?复制一个字节?两个字节?八个字节?代码在不同的 setter 中可能看起来相同,但它会编译成不同的机器码。

然后属性上还有复制和弱属性要考虑...

还在考虑这样做吗?

您需要熟悉 void ** 的含义,通过指针复制可变长度的数据等。然后看看 object_setInstanceVariableproperty_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