【问题标题】:Using one setter for all model iVars对所有模型 iVar 使用一个设置器
【发布时间】:2010-07-30 17:51:31
【问题描述】:

我的应用程序有一系列模型。在所有这些模型中,有(将有)大约 200 或 300 个实例变量。该应用程序将其持久数据存储在基于 Web 的服务器上(MySQL - 但我想这部分并不重要)。每当更新模型 iVar 时,我都需要调用服务器以更新该 iVar 的适当值。

我目前的模型策略是(头文件):

@interface MyModel : NSObject {

    NSString * firstName;
    NSString * lastName;
}

@property (readwrite, copy) NSString * firstName;
@property (readwrite, copy) NSString * lastName;

@end

(实现文件):

@implementation MyModel

@synthesize firstName;
@synthesize lastName;

-(id)init {

    [super init]

    [self setFirstName:@"George"];
    [self setLastName:@"Kastanza"];

    return self;
}

-(void)setFirstName:(NSString *)aName {

    // call method to update server with new value here
    firstName = aName;
}

-(void)setLastName:(NSString *)aName {

    // call method to update server with new value here
    lastName = aName;
}

@end

问题是,如果我有 200 或 300 个 iVar 都需要对服务器执行相同的更新调用,这意味着要编写 很多 个设置器。此外,如果我需要更改方法调用,我必须更新整个应用程序中每个 setter 中的每个方法。

是否有一个过程可以让我在设置之前先通过一个方法运行每组 iVar?

我曾想过每个模型对象只有一个 NSMutableDictionary 来存储所有 iVar 的,但这将 setter 和 getter 抽象化,并且可能会为这么多字典引入大量内存占用。但是,这样做意味着每次设置字典时,我都可以通过一种方法传递它。

据我了解,在运行时将 iVar 动态添加到对象模型被认为是一件坏事,因为指针引用可能依赖于模型的任何子类(子类指针不会偏移,除非完全重新编译是完成)。

非常感谢任何想法和建议。

更新

根据 Ole 的建议,这里是解决方案(尽管不幸的是,它使用的代码比几行多一点)...

在模型中,我添加了一个可以在需要时设置的方法。我没有直接从 init 调用该方法,因为添加从服务器返回的一大堆结果会触发每个添加对象的观察者。所以我在之后调用了方法,我已经初始化并更新了来自服务器的第一个抓取。

这是代码...

-(void)registerObservers {

    [self addObserver:self 
           forKeyPath:@"firstName"
              options:NSKeyValueObservingOptionNew 
              context:NULL];

    [self addObserver:self 
           forKeyPath:@"lastName" 
              options:NSKeyValueObservingOptionNew 
              context:NULL];
}

然后我将观察者添加到模型中:

-(void)observeValueForKeyPath:(NSString *)keyPath
                 ofObject:(id)object
                   change:(NSDictionary *)change
                  context:(void *)context {

    if ([keyPath isEqual:@"firstName"]) {
        // Do whatever I need to do
    }

    if ([keyPath isEqual:@"lastName"]) {
        // Do whatever I need to do
    }
}

在我的实际实现中,我还碰巧发布了一个设置为self 的对象通知,以便我可以更新任何应该在听但没有注意的东西(比如NSArrayControllers 中的东西)。

【问题讨论】:

    标签: objective-c model-view-controller nsmutabledictionary getter-setter


    【解决方案1】:

    使用Key-Value Observing。不过,您必须手动将自己注册为每个属性的观察者。

    【讨论】:

    • 感谢您的反馈。我不确定这是否真的能给我带来任何好处,因为那样我就会为每个 iVar 编写一个观察者,而不是为 setter 多写几行代码。我希望找到一种方法来做类似子类化 @synthesize 的事情,这样每个 setter 都会在我的对象模型上通过 1 个自定义方法,然后再交给 setter 本身。
    • 不,您将编写 400 行样板代码(200 行将自己注册为观察者,200 行将自己移除为观察者)但值更改时调用的实际方法始终相同.通过使用 Obj-C 运行时枚举类的所有属性,您还可以将样板代码简化为循环(参见 class_copyPropertyListproperty_getNameproperty_getAttributes)。
    • 好的 - 现在我喜欢这种方法! :-) 枚举对象以获取类属性可能是对我祈祷的巧妙回答。谢谢!!
    • 效果很好。我会尽快发布更新,以便其他人可以看到一个工作选项...
    猜你喜欢
    • 1970-01-01
    • 2014-12-16
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多