iOS 应用程序架构与 NSOperations

10
两个月前,我开始编写一款新的iPhone应用程序,为此,我创建了一个通用的RESTful Web服务,它允许我拥有很多必要的功能,如用户认证、用户配置文件、友好系统、媒体处理、消息系统等。在我的脑海中,有几种用例可以重用这个Web服务来开发未来的iPhone应用程序。
基于这种想法,我决定为此应用程序(和所有未来的应用程序)编写一个静态库,来处理所有繁重的工作,如媒体(图像、视频、音频)设置和处理、与Web服务通信、解析和映射结果、处理CoreData等。
鉴于我的应用程序存在很多并行任务运行的情况(最坏情况),例如用户当前更改其个人资料图片,同时应用程序将用户位置发送到服务器(在后台),并接收到新的推送通知。
因此,我决定将每个逻辑操作(如SendUserLocation或GetCurrentFriendList)封装在NSOperation中,并将它们添加到serviceQueue(NSOperationQueue)中。
每个操作都能够在成功从Web服务获取结果后生成子任务并进行处理。

alt text

一个典型的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]; 
    }
}

每个操作、请求(发送到服务器)和子任务都使用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:)];
最后一个问题:这种"架构"运行非常稳定,但是是否值得做?它会产生过多的开销吗?它有意义吗?你个人如何实现并发操作?
祝好, Henrik
附言:请随意编辑我的问题,提问(作为评论),因为这种思考而称呼我。我很难解释它,主要是因为我不是以英语为母语。别误会了,我写这篇文章不是为了炫耀什么。我想做的就是学习(也许写一些更高级的iPhone/Objective-C问题)。
3个回答

4

是的,如果要将其外包给服务请求并且您需要进行多个调用,则此类库(在我看来)不会过度使用,并且我编写了类似的内容。这种结构使我非常容易管理一个复杂的系统,具有非常复杂和多样化的任务。

我所做的主要设计差异是使用带有服务管理器的NSNotification。相反,我更喜欢使用协议/类型进行回调(操作持有对其的引用)。NSNotification非常重。在这种情况下,操作不保留侦听器/通知对象,但侦听器保留操作。如果关系是1-1,则允许取消。

另一个重要考虑因素是尽早定义线程。允许客户端定义他们想要在哪个线程上接收其响应。原因是如果通知/侦听器必须更新UI(例如,您正在使用UIKit或AppKit),则回调的约束或逻辑输入通常存在。因此,创建者可以告诉操作“你必须从主线程通知我”,或“我可以处理来自任何线程的响应”。这将大大减少您的控制器/侦听器/观察器代码和错误机会。


2
对于“子操作”:将它们放在队列中,使父操作成为每个子操作的依赖项(参见-[NSOperation addDependency:])。NSOperationQueue可以为您安排整个操作堆栈。我认为这很简单自然易用。

1

你刚刚描述了一个非常类似的架构,我在我的一些应用程序中也使用了它 :)

我有一个服务管理层,可以立即返回一组对象,然后在一段时间后返回更新后的一组对象。

NSArray *stuff = [serviceManager getFriendsForUser:@"Bob"];

然后,在服务器响应之后,会收到一个包含更新列表的NSNotification(在这种情况下是Bob的朋友)。

除了这个微小的改变,你的架构是一样的!

设置所有这些需要相当多的工作,但我认为从长远来看它是值得的,因为修复错误/扩展代码会更容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接