带有 NSOperations 的 iOS 应用架构 [英] iOS App Architecture with NSOperations

查看:19
本文介绍了带有 NSOperations 的 iOS 应用架构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两个月前,我开始编写一个新的 iPhone 应用程序,因此我创建了一个通用的 RESTFul Web 服务,它允许我拥有许多这些必要的功能,如用户身份验证、用户配置文件、友谊系统、媒体处理,消息系统等等.在我看来,有几个用例可以为未来的 iPhone 应用程序重用这个 web 服务.

Two month ago I started to write a new iPhone Application and for this reason I created a generic RESTFul web service, which allows me to have a lot of these necessary features like user authentication, user profiles, a friendship system, media processing, a messaging system and so on. In my mind there are several use cases to reuse this webservice for future iPhone applications.

带着这种心态,我决定为这个应用程序(以及所有未来的应用程序)编写一个静态库来处理所有繁重的工作,比如媒体(图像、视频、声音)设置和处理,与网络服务通信,解析和映射结果,处理 CoreData 等.

With this state of mind, I decided to write a static library for this application (and all future apps) that handles all the heavy lifting like media (image, video, sound) setup and processing, communicating with the web service, parsing and mapping of the results, handling CoreData and so on.

鉴于我的应用程序有很多并行任务正在运行的场景(最坏的情况),例如用户当前更改了他/她的个人资料图片,而应用程序将用户位置发送到服务器(在后台)并收到新的推送通知.

Given my application there are scenarios when a lot of parallel tasks are running (worst case) e.g. the user currently changes his/her profile picture, while the application sends the users location to the server (in the background) and a new push notification is received.

因此决定将每个逻辑操作(如 SendUserLocation 或 GetCurrentFriendList)封装在一个 NSOperation 中,并将它们添加到一个服务队列(NSOperationQueue)中.

So decided to encapsule each logical operation (like SendUserLocation or GetCurrentFriendList) in a NSOperation and add them to a serviceQueue (NSOperationQueue).

当操作成功从网络服务获得结果时,每个操作都能够产生子任务,现在应该处理它.

Each Operation is able to spawn subtasks when the operation successfully got a result from the webservice and should process it now.

典型的 ServiceManager 方法如下

A typical ServiceManager method looks like

- (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 作为通知名称,以在处理完成时通知父对象.如果操作中的所有内容都已完成,它会将通知发送回用户界面.

Each operation, request (to the server) and subTask uses a GUID as a notificationName to notify the parent object when it's done processing. If everything in an operation is done, it sends a notification back to the user interface.

也就是说,添加和删除子任务的代码是这样的

That said, the code for adding and removing subtasks looks like this

- (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 来启动一个特定的操作,比如

Now all I've got to do is to call the serviceManager in my gui to start a specific operation like

[self.core.serviceManager activateFriendsSync:nil onSuccess:nil];

如果我想注册一个观察者,我只需要像这样传递一个观察者对象和一个选择器

If I want to register an observer, I just pass an observer object and a selector like this

[self.core.serviceManager activateFriendsSync:self onSuccess:@selector(myMethod:)];

最后但并非最不重要的问题:架构"运行得非常好且稳定,但值得这样做吗?它是否会产生过多的开销?它甚至有意义吗?您个人是如何实现并发操作的?

Last but not least my question(s): The "architecture" runs very well and stable, but is it worth doing? Does it create too much overhead? Does it even make sense? How you, personally, implement concurrent operations?

最好的亨利克

附言随意编辑我的问题,提出问题(作为评论),为这种想法称呼我的名字.

P.S. Feel free to edit my question, ask questions (as a comment), call me names for this thinking.

我真的很难解释,主要是因为我的母语不是英语.不要误会我的意思.我写这篇文章不是为了炫耀.我想做的就是学习(也许写一个更高级的 iphone/objective c 问题)

I really had a hard time explaining it, basically because I'm not a native english speaker. And don't get me wrong. I didn't write this posting to show off in any kind. All I want to do is learn (and maybe to write a more advanced iphone / objective c question)

推荐答案

是的,如果它被用于服务请求并且您有很多调用要进行,那么这样的库并不是 (imo) 矫枉过正,我已经写过相似的东西.这种结构使我能够轻松管理一个复杂的系统,其中包含非常复杂和多样的任务.

yes, if it's being farmed out to service requests and you have many calls to make, then such a library is not (imo) overkill, and i have written something similar. this structure made it very easy for me to manage a complex system, with very complex and varied tasks.

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

the primary design difference i made was not to use NSNotification with a service manager. instead, i favored using protocols/types for callbacks (which the operation holds a reference to). NSNotification is quite heavy. in this case, the operation does not retain the listener(s)/notified objects, but the listeners retain the operation. if the relation is 1-1, then allow cancellation.

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

another major consideration is to define threading early on. allow clients to define which thread they want to receive their response on. the reason for this is that there is often a constraint or logical entry for the callback if the notified/listener must update the UI (e.g., you're using UIKit or AppKit). therefore, the creator can say to the operation 'you must inform me from the main thread', or 'i can handle the response from any thread'. this will reduce your controller/listener/observer code and chance for errors greatly.

这篇关于带有 NSOperations 的 iOS 应用架构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆