我是iOS开发新手并尝试解决以下问题。
在我的应用程序(使用REST API)中,我想在应用程序启动时向服务器发出初始请求以获取用户信息。我决定使用单独的服务类和单例方法。它向服务器发出一次请求,然后返回用户实例。
@implementation LSSharedUser
+ (LSUser *)getUser {
// make request to api server on the first call
// on other calls return initialized user
static LSUser *_sharedUser = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
LSHTTPClient *api = [LSHTTPClient create];
[api getUser:^(AFHTTPRequestOperation *operation, id user) {
_sharedUser = [[LSUser alloc] initWithDictionary:user];
} failure:nil];
});
return _sharedUser;
}
@end
我的问题是从服务器初始化全局数据的正确方法?如您所见,请求是异步的(使用AFNetworking lib),因此在请求完成之前它将返回null
。
这里的另一个问题是,一旦失败(例如连接错误),用户将永远为null。
答案 0 :(得分:0)
像这样更新您的代码
static LSUser *_sharedUser ;
+ (LSUser *)getUser {
// make request to api server on the first call
// on other calls return initialized user
if(_sharedUser){
//this will execute only at first time
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
LSHTTPClient *api = [LSHTTPClient create];
[api getUser:^(AFHTTPRequestOperation *operation, id user) {
_sharedUser = [[LSUser alloc] initWithDictionary:user];
return _sharedUser;
} failure:nil];
});
}
//this will execute 2nd time
return _sharedUser;
}
答案换行 - > 问题2)这里的另一个问题是,一旦失败(例如连接错误),用户将永远为null。 - >一旦_sharedUser初始化,用户将获得_sharedData。但是在共享数据未初始化之前,无论何时调用它都会返回null。
问题1)我的问题是从服务器初始化全局数据的正确方法?如您所见,请求是异步的(使用AFNetworking lib),因此在请求完成之前它将返回null。
更好的方法是实现自己的自定义委托方法。一旦获取请求或在该委托方法中执行您的工作的调用。 第一次:在获取或失败请求时执行调用委托方法。 第二次:if if block call delegate methods。
答案 1 :(得分:0)
基本方法需要异步设计。
假设你有一个异步方法:
- (void) loadUserWithCompletion:(void (^)(NSDictionary* user, NSError* error))completion;
您可以在“Continuation”(完成块)中执行您需要执行的任何操作:
[self loadUserWithCompletion:^(NSDictionary* params, NSError*error) {
if (user) {
User* user = [[User alloc] initWithDictionary:params];
// better we ensure we execute the following on the main thread:
dispatch_async(dispatch_get_main_queue(), ^{
self.model.user = user;
// If we utilize KVO, observers may listen on self.model.user
// which now get a notification.
// We also may to notify the user through an alert:
...
});
}
else {
// handler error
}
}];
使用异步编程风格时,在让用户执行任意任务(例如,标签按钮)时需要更加谨慎。您可以考虑禁用需要用户模型的任务。或者,在用户模型尚不可用时显示警报表。
通常,当用户模型最终可用时,您会使用一些“观察者”技术来获得通知。您可以使用KVO或完成处理程序,或使用专门针对这些问题的专用第三方库(例如Promise库)。
您还应该让用户随时取消该任务。然而,这需要更详细的方法,您可以在其中执行“可取消”任务,并且您可以在其中保留对这些任务的引用,以便能够向他们发送cancel
消息。