1

我正在使用一个名为 Restkit 的 iOS 库,它会自动将远程对象映射到本地对象。您可以通过使用 KVC 模式创建映射,然后使用映射加载来做到这一点。

虽然我了解它是如何工作的,但我不明白为什么某些部分以某些方式实现。例如,它使用单例模式,您可以在其中创建RKObjectMapping的实例,如下所示:

RKObjectMapping* articleMapping = [RKObjectMapping mappingForClass:[Article class]];
[articleMapping mapKeyPath:@"title" toAttribute:@"title"];
[articleMapping mapKeyPath:@"body" toAttribute:@"body"];
[articleMapping mapKeyPath:@"author" toAttribute:@"author"];
[articleMapping mapKeyPath:@"publication_date" toAttribute:@"publicationDate"];

但是,当实际使用它时,您可以通过调用RKObjectManager类的 sharedManager 来访问管理器,如下所示:

[[RKObjectManager sharedManager].mappingProvider setMapping:articleMapping
                                                 forKeyPath:@"articles"];

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/articles"
                                                  delegate:self];

我不明白的是,为什么还要麻烦将类实例化为articleMapping,而您只需要使用sharedManager之类的类方法/变量来访问它?为什么不做类似的事情:

[RKObjectMapping initWithClass:[Article class]];

我是一个新手,所以认为有充分的理由采用我不知道的这种模式。任何人都知道或理解为什么会以这种方式实施?

4

2 回答 2

1

将单例模式视为一种以“有序”方式管理全局对象的方式,并保证系统中仅存在一个此类对象。

因此,单例只是一种访问全局唯一对象的方法,该对象将在第一次尝试访问它时被实例化。

一旦您可以访问这个全局的、唯一的对象,它的行为就与您系统中的任何其他对象完全一样:它有自己的状态、方法等。

RestKit 的设计者可能采取的另一种方法是创建RKObjectManager一个只有类方法的类,并通过静态全局变量封装其状态。

这样,你就连实例化类的概念都没有了,直接调用它的方法就可以了。另一方面,这是一个非常糟糕的设计决策,IMO,在 Objective-C 中,因为语言缺乏对类成员变量的支持(与 C++ 相反),并且由于单例类的更高可重构性.

于 2012-10-14T06:56:02.533 回答
1

当一个对象需要访问与自身相关的数据时,它使用实例变量(ivars)来存储该数据。但是,实例变量是类的特定实例的一部分,而不是类本身 - 从类方法中,它们不能被访问。因此,当您谈论的管理器类是存储/访问其私有数据时,它使用共享实例(单例)来创建实例变量。如果仅将其用作类,则必须将其私有数据存储在全局变量中,这在 C 中被认为是不好的做法。

此外,如果您仔细观察,RKObjectManager该类具有属性。在 Objective-C 中,属性总是由底层实例变量支持(无论是在运行时、动态创建还是在编译时,以声明的方式创建)——这就是类不能有属性的原因,这就是为什么单例(一个类的实际实例)是必需的。

没有单例的示例(丑陋):

static int uglyGlobalVar;

@interface UglyClass: NSObject

+ (void)storeData:(int)data;

@end

@implementation UglyClass: NSObject

+ (void)storeData:(int)data
{
    uglyGlobalVar = data;
}

@end

单例示例(更好):

@interface GoodClass: NSObject {
    int data;
}

+ (GoodClass *)sharedInstance;

@property (nonatomic, assign) int data;

@end

@implementation GoodClass: NSObject

@syntehsize data;

// also implement sharedInstance here

@end

// then this class is usable as:
[GoodClass sharedInstance].data = 1337;
于 2012-10-14T06:56:13.397 回答