Objective-C完成块
问题描述:
我有一些问题,了解如何使用完成块调用方法为NSURLSessionTask。想知道如何正确调用方法getForecastAndConditionsForZipCode而不出错。谢谢!Objective-C完成块
Api.h:
typedef void (^WeatherAPICompletionBlock)(BOOL success, NSDictionary *result, NSError *error);
- (NSURLSessionDataTask *)getForecastAndConditionsForZipCode:(NSString *)zipCode withCompletionBlock:(WeatherAPICompletionBlock)completionBlock;
Api.m
- (NSURLSessionDataTask *)getForecastAndConditionsForZipCode:(NSString *)zipCode withCompletionBlock:(WeatherAPICompletionBlock)completionBlock
{
if (!self.APIKey) {
NSAssert(NO, @"API Key not set", nil);
completionBlock(NO, nil, [self missingAPIKeyError]);
return nil;
}
if (![NSThread isMainThread]) {
NSAssert(NO, @"API client method must be called on the main thread", nil);
completionBlock(NO, nil, [self genericError]);
return nil;
}
// Create the path
NSString *pathString = [NSString stringWithFormat:@"/api/%@%@/q/%@.json", self.APIKey, kWeatherAPIConditionsPath, zipCode];
// To avoid a retain cycle
__weak __typeof(self)weakSelf = self;
// Start the request
return [self GET:pathString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
if (!responseObject || ![responseObject isKindOfClass:[NSDictionary class]] || [responseObject count] == 0) {
DLog(@"Invalid responseObject: %@", responseObject);
completionBlock(NO, nil, [weakSelf genericError]);
return;
}
completionBlock(YES, responseObject, nil);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
DLog(@"Error with getForcastForLocation response: %@", error);
completionBlock(NO, nil, error);
}];
}
ViewController.m(这里是我不明白如何调用该方法getForecastAndConditionsForZipCode
import“Api.h”
- (IBAction)runApi:(UIButton *)sender {
WeatherAPIClient *weatherApiClient = [[WeatherAPIClient alloc] init];
NSURLSessionDataTask *test = [weatherApiClient getForecastAndConditionsForZipCode:@"55345" withCompletionBlock:^(YES, result, error)];
}
答
在Xcode中使用代码完成来简化。
类型:
NSURLSessionDataTask *test = [weatherApiClient getForecast
,并选择匹配方法的名称。然后在withCompletionBlock:
后标签到占位符并按回车。神奇地你会结束:
NSURLSessionDataTask *test = [weatherApiClient getForecastAndConditionsForZipCode:@"55345" withCompletionBlock:^(BOOL success, NSDictionary *result, NSError *error) {
}];
现在你需要填写大括号之间的部分。这是您在处理完成时要调用的块。您将获得success
,result
和error
的值。你可能想是这样的:
NSURLSessionDataTask *test = [weatherApiClient getForecastAndConditionsForZipCode:@"55345" withCompletionBlock:^(BOOL success, NSDictionary *result, NSError *error) {
if (success) {
// do something with result
} else {
NSLog(@"Uh oh - error getting forecast: %@", error);
}
}];
顺便说一句 - 你的getForecastAndConditionsForZipCode:withCompletionBlock:
的执行不应该承担完成块是通过确保您后卫完成块的所有调用:
if (completionBlock) {
completionBlock(YES, someResult, nil); // or whatever values you need to send
}
此代码。确保你的应用程序不会崩溃,如果有人打电话:
NSURLSessionDataTask *test = [weatherApiClient getForecastAndConditionsForZipCode:@"55345" withCompletionBlock:nil];
+0
这基本上就是我所做的。唯一的问题是xcode不允许你填写它,你需要实际输入它手动工作。谢谢,我有它的工作? – jKraut 2014-09-26 12:17:03
说真的,你可以改变你的问题的标题? – gnasher729 2014-09-25 23:13:23
@ gnasher729,你对他的头衔有“异议”?我没有提出你的反对意见。 :) – 2014-09-26 00:46:14