我是iOS编程新手,还在学习。
编辑:!!!!!!我的代码中的所有内容都有效。我的问题是关于我使用的委托模式, 如果我在背景中产生我不知道的问题,或者是否有更好的方法来处理我在AFNetworking中的情况......
我通过继承AFHTTPSessionManager为我的应用创建了一个API。 我的API创建一个单例并返回它并为各种请求提供公共函数。这些函数创建参数列表,并在服务器上发出GET请求,如下所示:
- (void)getCharacterListForKeyID:(NSString *)keyID vCode:(NSString *)vCode sender:(id)delegate
{
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
parameters[@"keyID"] = keyID;
parameters[@"vCode"] = vCode;
[self GET:@"account/Characters.xml.aspx" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
self.xmlWholeData = [NSMutableDictionary dictionary];
self.errorDictionary = [NSMutableDictionary dictionary];
NSXMLParser *XMLParser = (NSXMLParser *)responseObject;
[XMLParser setShouldProcessNamespaces:YES];
XMLParser.delegate = self;
[XMLParser parse];
if ([delegate respondsToSelector:@selector(EVEAPIHTTPClient:didHTTPRequestWithResult:)]) {
[delegate EVEAPIHTTPClient:self didHTTPRequestWithResult:self.xmlWholeData];
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
if ([delegate respondsToSelector:@selector(EVEAPIHTTPClient:didFailWithError:)]) {
[delegate EVEAPIHTTPClient:self didFailWithError:error];
}
}];
}
我之前使用的是普通协议/委托方法。但是,一旦我像这样不止一次地调用这个API :(它就像这样:)
EVEAPIHTTPClient *client = [EVEAPIHTTPClient sharedEVEAPIHTTPClient];
client.delegate = self;
[client getCharacterListForKeyID:self.keyID vCode:self.vCode];
以前的呼叫被委托被覆盖了。所以我改变了以上的风格。将发送者作为参数传递给函数:
EVEAPIHTTPClient *client = [EVEAPIHTTPClient sharedEVEAPIHTTPClient];
[client getCharacterListForKeyID:self.keyID vCode:self.vCode sender:self];
我将此发件人传递给GET请求的成功和失败块。
我想知道的是:“这是一个很好的编程习惯吗?”如果可能的话,应该避免将对象传递给这样的块?在AFHTTPSessionManager中是否还有其他更优雅的方法来处理这种类型的工作(使用不同的参数反复进行相同的GET请求并将结果返回给相应的请求所有者)更优雅?
答案 0 :(得分:2)
当涉及简单性和异步请求处理时,委托模式就会动摇。你应该使用块,这是一个例子
您的服务器类:
static NSString *const kNews = @"user_news/"; // somewhere above the @implementation
- (NSURLSessionDataTask *)newsWithPage:(NSNumber *)page
lastNewsID:(NSNumber *)lastNewsID
completion:(void (^)(NSString *errMsg, NSArray *news, NSNumber *nextPage))completionBlock {
return [self GET:kNews
parameters:@{@"page" : page,
@"news_id" : lastNewsID
}
success:^(NSURLSessionDataTask *task, id responseObject) {
NSArray *news = nil;
NSNumber *nextPage = nil;
NSString *errors = [self errors:responseObject[@"errors"]]; // process errors
if ([responseObject[@"status"] boolValue]) {
news = responseObject[@"news"];
nextPage = responseObject[@"next_page"];
[self assignToken];
}
completionBlock(errors, news, nextPage);
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
NSString *errors = [self errors:error];
completionBlock(errors, nil, nil);
}];
}
来电者
- (void)dealloc {
[_task cancel]; // you don't want this task to execute if user suddenly removes your controller from the navigation controller's stack
}
- (void)requestNews {
typeof(self) __weak wself = self; // to avoid the retain cycle
self.task = [[GSGServer sharedInstance] newsWithPage:self.page
lastNewsID:self.lastNewsID
completion:^(NSString *errMsg, NSArray *news, NSNumber *nextPage) {
if (errMsg) {
[GSGAppDelegate alertQuick:errMsg]; // shortcut for posting UIAlertView, uses errMsg for message and "Error" as a title
return;
}
[wself.news addObjectsFromArray:news];
wself.lastNewsID = [wself.news firstObject][@"id"];
wself.page = nextPage;
[wself.tableView reloadData];
}];
}