两个月前我开始编写一个新的iPhone应用程序,因此我创建了一个通用的RESTFul Web服务,它允许我拥有许多这些必要的功能,如用户身份验证,用户配置文件,友谊系统,媒体处理,消息传递系统等。在我看来,有几个用例可以将这个web服务重用于未来的iPhone应用程序。
有了这种心态,我决定为这个应用程序(以及所有未来的应用程序)编写一个静态库,处理所有繁重的工作,如媒体(图像,视频,声音)设置和处理,与Web服务通信,解析和映射结果,处理CoreData等。
鉴于我的应用程序,存在许多并行任务正在运行的情况(最坏情况),例如 用户当前更改他/她的个人资料图片,同时应用程序将用户位置发送到服务器(在后台)并且接收新的推送通知。
因此决定在NSOperation中封装每个逻辑操作(如SendUserLocation或GetCurrentFriendList)并将它们添加到serviceQueue(NSOperationQueue)。
当操作成功从Web服务获得结果并且现在应该处理它时,每个操作都能够生成子任务。
典型的ServiceManager方法如
- (void)activateFriendsSync:(id)observer onSuccess:(SEL)selector {
ELOSyncFriends *opSyncFriends = [[ELOSyncFriends alloc] initWithSM:self];
[self ELServiceLogger:opSyncFriends];
[serviceQueue addOperation:opSyncFriends];
if(observer) {
[self registerObserver:observer selector:selector name:opSyncFriends.notificationName];
}
}
每个操作,请求(到服务器)和subTask都使用GUID作为notificationName来在完成处理时通知父对象。如果操作中的所有内容都已完成,它会将通知发送回用户界面。
也就是说,添加和删除子任务的代码如下所示
- (void)removeSubTask:(NSNotification*)notification {
ELRequest *request = (ELRequest*)[notification object];
[subTasks removeObjectIdenticalTo:request.notificationName];
if([subTasks count] == 0) {
// all SubTaks done, send notification to parent
[serviceManager.notificationCenter postNotificationName:self.notificationName object:request];
}
}
- (NSString*)addSubTask {
NSString* newName = [self GetUUID];
[subTasks addObject:[newName retain]];
[serviceManager.notificationCenter addObserver:self selector:@selector(removeSubTask:) name:newName object:nil];
return newName;
}
- (NSString *)GetUUID {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return [(NSString *)string autorelease];
}
现在我要做的就是在我的gui中调用serviceManager来启动一个特定的操作,如
[self.core.serviceManager activateFriendsSync:nil onSuccess:nil];
如果我想注册一个观察者,我只是传递一个观察者对象和一个这样的选择器
[self.core.serviceManager activateFriendsSync:self onSuccess:@selector(myMethod:)];
最后但并非最不重要的是我的问题:“架构”运行良好且稳定,但值得做吗?它会产生太多开销吗?它甚至有意义吗?您个人如何实施并发操作?
最佳亨利克
P.S。随意编辑我的问题,提出问题(作为评论),给我这个想法的名字。
我真的很难解释它,主要是因为我不是母语为英语的人。不要误解我的意思。我没有写这篇文章以任何形式炫耀。我想做的就是学习(也许写一个更高级的iphone / objective c问题)
答案 0 :(得分:4)
我所做的主要设计差异是不与服务管理器一起使用NSNotification。相反,我倾向于使用协议/类型进行回调(操作持有引用)。 NSNotification很重。在这种情况下,操作不保留侦听器/通知对象,但侦听器保留操作。如果关系是1-1,那么允许取消。
另一个主要考虑因素是尽早定义线程。允许客户端定义他们想要接收响应的线程。这样做的原因是,如果通知/监听器必须更新UI(例如,您正在使用UIKit或AppKit),则通常会有回调的约束或逻辑条目。因此,创建者可以对操作说'你必须从主线程通知我',或'我可以处理来自任何线程的响应'。这将大大减少你的控制器/监听器/观察者代码和错误的可能性。
答案 1 :(得分:2)
对于“子操作”:如何将它们放在队列中,父操作是每个子操作的依赖项( cf。-[ NSOperation addDependency: ]
)? NSOperationQueue可以为您排序整个操作。我认为这很简单,也很自然。
答案 2 :(得分:1)
您刚刚描述了我在一些应用程序中使用的非常相似的架构:)
我的服务管理器层立即返回一组对象,然后在一段时间后返回更新的集合,即
NSArray *stuff = [serviceManager getFriendsForUser:@"Bob"];
然后,在服务器响应之后,收到一个包含更新列表的NSNotification(在这种情况下为Bob的朋友)。
除了这个微小的变化,你的架构是一样的!
要完成所有设置是相当多的工作,但我认为从长远来看这是值得的,因为修复错误/扩展代码要容易得多。