所以在我看来这里有一个Catch-22的情况.请注意以下广泛(且巧妙)持有的应用程序架构的立场:
你是如何解决这个问题的?当视图控制器从nib中唤醒时,是否使用NotificationCenter发布通知,然后在上下文引用中传递app delegate?这是我能想到的第一种方式,只有#1和#2,但这对我来说也是一种扭曲.
有更优雅的方式吗?
编辑:初始化视图控制器时进行通知可能是一种竞争条件,因为如果您正在使用Storyboard,您的tabbar的子视图控制器往往在启动时被初始化(尽管sans-view加载).所以你必须在viewDidLoad中做这样的通知,这对于MVC约定来说是一个坏主意.在用户执行与视图相关的任何操作之前,它还会将您的任务与数据模型(例如预缓存性能)相关联.
背景:我有一个托管对象,Car.我在localhost/cars/search上有一个RESTful搜索API.返回的结果是来自服务器端的Car对象,但我只想保存用户选择的那个.当他们退出搜索时,我想要丢弃剩下的汽车.
起初我都喜欢:
@interface Car : NSManagedObject //<--- managed object
@property (nonatomic, strong) NSNumber* year;
@property (nonatomic, strong) NSString* make;
@property (nonatomic, strong) NSString* model;
@end
@interface TransientCar : NSObject //<--- regular NSObject!
@property (nonatomic, strong) NSNumber* year;
@property (nonatomic, strong) NSString* make;
@property (nonatomic, strong) NSString* model;
@end
Run Code Online (Sandbox Code Playgroud)
我将REST API搜索结果JSON映射到TransientCar对象以显示搜索结果,但不将它们保存到上下文中.默认情况下,如果映射托管对象,RestKit将调用其+对象便利工厂来创建对象并将其插入当前上下文(硬编码为sharedManager的对象库的上下文,顺便说一句!)
这似乎不可持续.所以现在我只是使用NSMutableDictionary来保存搜索结果数据,直到用户点击详细视图并执行一些值得保存真实托管对象的内容:
RKObjectMapping* tempCarMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[tempCarMapping mapKeyPathsToAttributes:
@"year", @"year",
@"make", @"make",
@"model", @"model",
nil];
Run Code Online (Sandbox Code Playgroud)
这是一个好习惯吗?使用NSMutableDictionary作为临时表示,直到用户做了保证在上下文中插入新对象的操作?我有点喜欢使用原始托管对象子类来表示数据,但不知何故能够将其标记为"不要保留"或者其他东西,但每次我这样做时我觉得我正在与框架作斗争(和比赛条件).我还尝试通过创建一个新的RKObjectManager来使用临时/一次性上下文,然后只是清除其整个上下文,但RestKit的ActiveRecord类的+ managedObjectContext方法被硬编码返回:
[[[RKObjectManager sharedManager] objectStore] managedObjectContext];
Run Code Online (Sandbox Code Playgroud)
这种方式破坏了对临时/垃圾数据使用临时上下文的可能性.
大多数RESTful API都会路由访问资源,比如Rabbit对象,如下所示:
GET /rabbits <--- GET all rabbits. HTTP GET
GET /rabbits/:rabbit_id <--- GET one rabbit. Also HTTP GET
POST /rabbits
PUT /rabbit/:rabbit_id
Run Code Online (Sandbox Code Playgroud)
但是,RestKit不允许我有两个具有相同HTTP谓词的路由,因此不可能将两个GET路由添加到RKObjectManager的RouteSet:
[manager.router.routeSet addRoute:[RKRoute routeWithClass:[Rabbit class]
pathPattern:@"rabbits"
method:RKRequestMethodGET]];
[manager.router.routeSet addRoute:[RKRoute routeWithClass:[Rabbit class]
pathPattern:@"rabbits/:rabbitID"
method:RKRequestMethodGET]];
//BOOM! Assertion failure
Run Code Online (Sandbox Code Playgroud)
这会导致断言失败:"无法添加具有与现有路由相同的类和方法的路由."
为什么我不能添加具有相同类和方法的路由?该路径是不同的.我怎么能得到兔子的列表以及ID的单个兔子?我知道几种解决方法,但我觉得这不是我应该解决的问题.