返回类型的方法是NSArray,所以当我调用这个方法时,我得到nil或空数组。这是它在我的方法实现之下:
- (NSArray *)startParsing {
__block NSArray *array;
allProductsID = [[NSMutableArray alloc] init];
NSString *string = [NSString stringWithFormat:@"http://%@:@%@",kPrestaShopAPIKey, kPrestaShopURLString];
NSURL *url = [NSURL URLWithString:string];
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:url];
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
[manager GET:@"categories/21" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSXMLParser *parser = (NSXMLParser *)responseObject;
[parser setShouldProcessNamespaces:YES];
parser.delegate = self;
[parser parse];
//NSLog(@"First response %@", responseObject);
for (int i = 0; i< [[self.xmlShop objectForKey:@"product"] count]; i++) {
//NSLog(@"Second ID --> %@", [self.xmlShop objectForKey:@"product"][i]);
NSString *productID = [NSString stringWithFormat:@"products/%@", [[self.xmlShop objectForKey:@"product"][i] objectForKey:@"id"]];
[allProductsID addObject:productID];
}
array = [allProductsID copy];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error occured %@", [error localizedDescription]);
}];
return array;
}
任何人都可以帮我解决这个问题吗?
答案 0 :(得分:7)
正如Quentin已经提到的那样,你不能直接这样做,因为你在内部执行异步请求。这意味着您的程序启动请求,然后继续其下一个语句,并且不等待请求完成。你应该做的是
startParsing
方法的回调(与实际请求回调使用块的方式相同)这样可以举例如下:
- (void)startParsing:(void (^)(NSArray*))parsingFinished {
allProductsID = [[NSMutableArray alloc] init];
NSString *string = [NSString stringWithFormat:@"http://%@:@%@",kPrestaShopAPIKey, kPrestaShopURLString];
NSURL *url = [NSURL URLWithString:string];
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:url];
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
[manager GET:@"categories/21" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
// do your parsing...
parsingFinished([allProductsID copy]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
parsingFinished([[NSArray alloc] init]);
// or return nil or provide a parsingFailed callback
}];
}
然后你会像
一样调用[yourObject startParsing:^(NSArray *parsedData) {
// do something with the parsed data
}];
答案 1 :(得分:2)
你不能。
在您的情况下,块是异步执行的。这意味着在执行块时,您的方法可能已经返回。
您需要调用另一个方法或从块中发送NSNotification以传递数组。
答案 2 :(得分:0)
应该返回枚举值的方法
- (RXCM_TroubleTypes) logic_getEnumValueOfCurrentCacheProblem
{
RXCM_TroubleTypes result = RXCM_HaveNotTrouble;
NetworkStatus statusConnection = [self network_typeOfInternetConnection];
RXCM_TypesOfInternetConnection convertedNetStatus = [RXCM convertNetworkStatusTo_TypeOfInternetConnection:statusConnection];
BOOL isAllowed = [self someMethodWith:convertedNetStatus];
if (isAllowed){
return RXCM_HaveNotTrouble;
}else {
return RXCM_Trouble_NotSuitableTypeOfInternetConnection;
}
return result;
}
使用block调用委托人方法的方法。 并等待答案。 在这里我使用while循环。只需检查每隔0.5秒的答案
- (BOOL) isUserPermissioned:(RXCM_TypesOfInternetConnection)newType
{
__block BOOL isReceivedValueFromBlock = NO;
__block BOOL result = NO;
__block BOOL isCalledDelegateMethod = NO;
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_sync(aQueue,^{
while (!isReceivedValueFromBlock) {
NSLog(@"While");
if (!isCalledDelegateMethod){
[self.delegate rxcm_isAllowToContinueDownloadingOnNewTypeOfInternetConnection:newType
completion:^(BOOL isContinueWorkOnNewTypeOfConnection) {
result = isContinueWorkOnNewTypeOfConnection;
isReceivedValueFromBlock = YES;
}];
isCalledDelegateMethod = YES;
}
[NSThread sleepForTimeInterval:0.5];
}
});
return result;
}
ViewController中的委托方法
- (void) rxcm_isAllowToContinueDownloadingOnNewTypeOfInternetConnection:(RXCM_TypesOfInternetConnection)newType
completion:(void(^)(BOOL isContinueWorkOnNewTypeOfConnection))completion
{
__weak ViewController* weak = self;
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Alert"
message:@"to continue download on the new type of connection"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"YES" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completion(YES);
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"NO" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completion(NO);
}];
[alert addAction:cancel];
[alert addAction:ok];
[weak presentViewController:alert animated:YES completion:nil];
});
}