我使用名为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]];
我是一个新手,所以认为有一个很好的理由采取我不知道的这种模式。任何人都知道或理解为什么会这样实现?
答案 0 :(得分:1)
将单例模式视为以“有序”方式管理全局对象的一种方式,并保证系统中只存在一种类型。
因此,单例只是一种访问全局唯一对象的方法,该对象将在首次尝试访问它时进行实例化。
一旦您访问了这个全局唯一对象,它的行为就像您系统中的任何其他对象一样:它有自己的状态,方法等。
RestKit的设计者可能采取的另一种方法可能是使RKObjectManager
只使用类方法并通过静态全局变量封装其状态。
通过这种方式,你甚至没有实例化类的概念,并且可以直接调用它的方法。另一方面,鉴于语言缺乏对类成员变量的支持(与C ++相反),以及由于单例类的可重构性较高,这在Objective-C中是一个糟糕的设计决策IMO。
答案 1 :(得分: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;