14

我正在使用 parse.com API(提供 API 以将数据保存在其服务器上的托管后端)开发一个应用程序。我希望能够在线和离线无缝地使用该应用程序。为此,我需要使用一个队列,我可以在其中放置需要网络访问的块。当网络确实可用时,应该串行执行块,当网络离线时,应该暂停队列处理。

当网络变得可用/不可用时,我正在考虑将 GCD 与挂起/恢复一起使用。我想知道是否有更好的选择?如果将应用程序放在后台,这会起作用吗?这里的一个典型例子是,当网络不可用(排队)时,用户会保存一些数据,然后将应用程序置于后台。现在当网络可用时,是否可以在后台自动进行保存?

4

5 回答 5

16

我完全按照您使用NSOperationQueue. 首先,创建一个串行队列并默认挂起它:

self.operationQueue = [[[NSOperationQueue alloc] init] autorelease];
self.operationQueue.maxConcurrentOperationCount = 1;
[self.operationQueue setSuspended:YES];

然后,创建一个 Reachability 实例并注册kReachabilityChangedNotification

[[NSNotificationCenter defaultCenter] addObserver:manager
                                         selector:@selector(handleNetworkChange:) 
                                             name:kReachabilityChangedNotification 
                                           object:nil];

[self setReachability:[Reachability reachabilityWithHostName:@"your.host.com"]];
[self.reachability startNotifier];

现在,当网络状态发生变化时启动和停止队列:

-(void)handleNetworkChange:(NSNotification *)sender {
    NetworkStatus remoteHostStatus = [self.reachability currentReachabilityStatus];

    if (remoteHostStatus == NotReachable) {
        [self.operationQueue setSuspended:YES];
    }
    else {
        [self.operationQueue setSuspended:NO];
    }
}

您可以使用以下命令对块进行排队:

[self.operationQueue addOperationWithBlock:^{
    // do something requiring network access
}]; 

暂停队列只会阻止操作启动——它不会暂停正在进行的操作。在执行操作时,您总是有可能会丢失网络,因此您应该在操作中考虑到这一点。

于 2012-05-25T15:46:33.233 回答
2

查看-[PFObject saveEventually]。这应该会自动执行您尝试执行的操作,并具有抵御应用程序终止的额外好处。

于 2012-05-30T01:01:33.587 回答
1

你看过使用AFNetworking库吗?我相信它与 Reachabiltiy 挂钩,并且可以完全按照您的意愿行事。

于 2012-05-24T17:26:19.470 回答
0

我是 GCD 和 Blocks 的忠实粉丝,但为此我会使用NSOperationQueue. 我认为 GCD 更适合低级的东西。NSOperationQueue您可以取消某些操作。您还可以表达对其他操作的依赖关系(如果您的应用程序需要这样做)。

于 2012-05-25T08:27:07.833 回答
0

我们在内部项目中遇到了类似的问题,所以我编写了一个名为 OfflineRequestManager 的 pod,它包装了任何网络请求,并允许无论连接如何都可以将其加入队列。如果您将 Parse 请求(或其他)包装在符合 OfflineRequest 的对象中,则管理器会将其排入队列并确保在连接允许时它会发出。

最简单的用例看起来像

import OfflineRequestManager

class SimpleRequest: OfflineRequest {
    func perform(completion: @escaping (Error?) -> Void) {
        doMyParseThing(withCompletion: { response, error in
            handleResponse(response)
            completion(error)
        })
    }
}
///////
OfflineRequestManager.defaultManager(queueRequest: SimpleRequest())
于 2018-03-27T18:54:55.913 回答