1

AFHTTPRequestOperationでAFNetworkingを使用して、WebサービスからXMLデータをプルしています。これは正常に機能しており、必要なデータを取得していますが、このデータをオブジェクトに分割し、このデータでNSMutableArrayを初期化する必要があります。これは完了ブロックで機能していますが、メソッドで配列を返す直前にデータが失われていますか?どうすればよいですか?

これが私のコードの一部です:

NSMutableArray *result = [[NSMutableArray alloc] init];    
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSString* response = [operation responseString];
    NSData* xmlData = [response dataUsingEncoding:NSUTF8StringEncoding];
    NSError *xmlError;
    GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&xmlError];
    NSArray *allElements = [doc.rootElement elementsForName:@"Misc"];
    for (GDataXMLElement *current in allElements)
    {
        NSString *titel;
        NSString *tekst;

        NSArray *titels = [current elementsForName:@"Titel"];
        if(titels.count > 0)
        {
            GDataXMLElement *firstTitel = (GDataXMLElement *) [titels objectAtIndex:0];
            titel = firstTitel.stringValue;
        } else continue;

        NSArray *teksts = [current elementsForName:@"Tekst"];
        if(teksts.count > 0)
        {
            GDataXMLElement *firstTekst = (GDataXMLElement *) [teksts objectAtIndex:0];
            tekst = firstTekst.stringValue;
        } else continue;

        HVMGUniversalItem *item = [[HVMGUniversalItem alloc] initWithTitel:titel AndTekst:tekst];
        [result addObject:item];
    }
    NSLog(@"%i", result.count);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", [operation error]);
}];

[operation start];
NSLog(@"%i", result.count);
return result;

私は何が間違っているのですか?戻るときにデータが配列に存在しないのはなぜですか?

4

1 に答える 1

1

戻るときにデータが配列に存在しないのはなぜですか?

AFNetworkingは非同期パターンを使用するためです。したがって、操作が完了する前に戻りコードが実行されます。

別のアプローチを使用する必要がありますか、それともAFNetworkingがデータを同期的に(ブロック内で)返すことができますか?。後者はお勧めできません。

解決策は次のとおりです。

->NSOperationQueue操作を含むクラス内にを作成します。のようなクラスのプロパティとして作成します。

@property (nonatomic, strong, readonly) NSOperationQueue* downloadQueue;

- (NSOperationQueue*)downloadQueue
{
    if(downloadQueue) return downloadQueue;

    downloadQueue = // alloc init here
}

->配列のプロパティを作成します(それも合成します)

@property (nonatomic, strong) NSMutableArray* result;

->のような特定のメソッド内でコードをラップしますdoOperation

self.result = [[NSMutableArray alloc] init];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];

__weak YourClass* selfBlock = self; 

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSString* response = [operation responseString];
    NSData* xmlData = [response dataUsingEncoding:NSUTF8StringEncoding];
    NSError *xmlError;
    GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&xmlError];
    NSArray *allElements = [doc.rootElement elementsForName:@"Misc"];
    for (GDataXMLElement *current in allElements)
    {
        NSString *titel;
        NSString *tekst;

        NSArray *titels = [current elementsForName:@"Titel"];
        if(titels.count > 0)
        {
            GDataXMLElement *firstTitel = (GDataXMLElement *) [titels objectAtIndex:0];
            titel = firstTitel.stringValue;
        } else continue;

        NSArray *teksts = [current elementsForName:@"Tekst"];
        if(teksts.count > 0)
        {
            GDataXMLElement *firstTekst = (GDataXMLElement *) [teksts objectAtIndex:0];
            tekst = firstTekst.stringValue;
        } else continue;

        HVMGUniversalItem *item = [[HVMGUniversalItem alloc] initWithTitel:titel AndTekst:tekst];
        [selfBlock.result addObject:item];
    }
    NSLog(@"%i", result.count);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", [operation error]);
}];

[downloadQueue addOperation:operation];

->オブジェクトに通知を送信させるように通知する必要がある場合resultは、デリゲートパターンなどを使用します。

お役に立てば幸いです。

于 2012-07-08T15:28:43.317 に答える