0

このコードを使用して、いくつかのNSOperationsを作成し、それらをキューに追加します。

HUD = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
        //HUD.labelText = @"Downloading..";
        //HUD.dimBackground = YES;

        /* Operation Queue init  */
        NSOperationQueue *queue = [NSOperationQueue new];

        // Spawn request operations & add them to queue
        SoapRequestOperation *operation = [[SoapRequestOperation alloc] initWithRequest:@"<?xml version=\"1.0\" encoding=\"utf-8\"?> <soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <Categories xmlns=\"http://tempuri.org/\"> <UID>string</UID> <Username>string</Username> <Password>string</Password> </Categories>      </soap:Body> </soap:Envelope>" andValue:@"Categories"];

        [queue addOperation:operation];

        operation = [[SoapRequestOperation alloc] initWithRequest:@"<?xml version=\"1.0\" encoding=\"utf-8\"?> <soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <Currencies xmlns=\"http://tempuri.org/\"> <UID>string</UID> <Username>string</Username> <Password>string</Password> </Currencies>      </soap:Body> </soap:Envelope>" andValue:@"Currencies"];

        [queue addOperation:operation];

        operation = [[SoapRequestOperation alloc] initWithRequest:@"<?xml version=\"1.0\" encoding=\"utf-8\"?> <soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <Nominals xmlns=\"http://tempuri.org/\">   <UID>string</UID> <Username>string</Username> <Password>string</Password> </Nominals> </soap:Body> </soap:Envelope>" andValue:@"Nominals"];

        [queue addOperation:operation];

        operation = [[SoapRequestOperation alloc] initWithRequest:@"<?xml version=\"1.0\" encoding=\"utf-8\"?> <soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <Projects xmlns=\"http://tempuri.org/\">   <UID>string</UID> <Username>string</Username> <Password>string</Password> </Projects>        </soap:Body> </soap:Envelope>" andValue:@"Projects"];

        [queue addOperation:operation];

        operation = [[SoapRequestOperation alloc] initWithRequest:@"<?xml version=\"1.0\" encoding=\"utf-8\"?> <soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <Register xmlns=\"http://tempuri.org/\">   <UID>string</UID> <Username>string</Username> <Password>string</Password> <OrganisationCode>string</OrganisationCode> </Register> </soap:Body> </soap:Envelope>" andValue:@"Register"];

        [queue addOperation:operation];

        [queue waitUntilAllOperationsAreFinished];

        [self reloadTableData];

        HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]];
        HUD.mode = MBProgressHUDModeCustomView;
        [HUD hide:YES afterDelay:2];

これは、NSOperationサブクラスの.mファイルです。

#import "SoapRequestOperation.h"
#import "Currency.h"
#import "Category.h"
#import "Project.h"
#import "Constants.h"

@implementation SoapRequestOperation

@synthesize request, value;

-(id) initWithRequest:(NSString *)l_Request andValue:(NSString *)l_Value{
    if (self = [super init]) {
        /* do most of initialization */
        self.request = l_Request;
        self.value = l_Value;
        xmlBlock = 0;
        appDelegate = [[UIApplication sharedApplication] delegate];
    }
    return(self);
}

- (void) main {
    if ([value isEqualToString:@"Category"]){
        xmlBlock = CATEGORY;
    }
    else if ([value isEqualToString:@"Currency"]){
        xmlBlock = CURRENCY;
    }
    else if ([value isEqualToString:@"Nominal"]){
        xmlBlock = NOMINAL;
    }
    else if ([value isEqualToString:@"Project"]){
        xmlBlock = PROJECT;
    }
    else {
        xmlBlock = REGISTER;
    }

    NSString *soapMsg = request;
    //---print it to the Debugger Console for verification---
    NSLog(@"%@", soapMsg);
    NSURL *url = [NSURL URLWithString:
                  @"http://www.$^$%£%@%^£.co.uk/$$^$^£$^£.asmx"];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    //---set the headers---
    NSString *msgLength = [NSString stringWithFormat:@"%d",
                           [soapMsg length]];
    [req addValue:@"text/xml; charset=utf-8"
forHTTPHeaderField:@"Content-Type"];
    [req addValue:[NSString stringWithFormat:@"http://tempuri.org/%@", value]
forHTTPHeaderField:@"SOAPAction"];
    [req addValue:msgLength forHTTPHeaderField:@"Content-Length"];
    //---set the HTTP method and body---
    [req setHTTPMethod:@"POST"];
    [req setHTTPBody: [soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
    //[activityIndicator startAnimating];
    conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    if (conn) {
        webData = [NSMutableData data];
    }
}

-(void) connection:(NSURLConnection *) connection
didReceiveResponse:(NSURLResponse *) response {
    [webData setLength: 0];
}

-(void) connection:(NSURLConnection *) connection
    didReceiveData:(NSData *) data {
    [webData appendData:data];
}

-(void) connection:(NSURLConnection *) connection
  didFailWithError:(NSError *) error {

}

-(void) connectionDidFinishLoading:(NSURLConnection *) connection {
    NSLog(@"DONE. Received Bytes: %d", [webData length]);
    NSString *theXML = [[NSString alloc]
                        initWithBytes: [webData mutableBytes]
                        length:[webData length]
                        encoding:NSUTF8StringEncoding];
    //---shows the XML---
    NSLog(@"%@", theXML);

    xmlParser = [[NSXMLParser alloc] initWithData: webData];
    [xmlParser setDelegate: self];
    [xmlParser setShouldResolveExternalEntities:YES];
    [xmlParser parse];

}

//---when the start of an element is found---
-(void) parser:(NSXMLParser *) parser
didStartElement:(NSString *) elementName
  namespaceURI:(NSString *) namespaceURI
 qualifiedName:(NSString *) qName
    attributes:(NSDictionary *) attributeDict {
    currentElement = [elementName copy];

    //Category
    if( [currentElement isEqualToString:@"Item"])
    {
        category = [[NSMutableDictionary alloc] init];
        categoryName = [[NSMutableString alloc] init];
    }

    //Currency
    if ([currentElement isEqualToString: @"Currency"]) {
        currency = [[NSMutableDictionary alloc] init];
        countryName = [[NSMutableString alloc] init];
        currencyName = [[NSMutableString alloc] init];
        currencyUnit = [[NSMutableString alloc] init];
        shortName = [[NSMutableString alloc] init];
    }

    //Nominal
    if( [currentElement isEqualToString:@"Nominal"])
    {
        nominal = [[NSMutableDictionary alloc] init];
        name = [[NSMutableString alloc] init];
        description = [[NSMutableString alloc] init];
        paid = [[NSMutableString alloc] init];
    }

    //Project
    if( [currentElement isEqualToString:@"Project"])
    {
        project = [[NSMutableDictionary alloc] init];
        projectName = [[NSMutableString alloc] init];
        projectDescription = [[NSMutableString alloc] init];
    }

    //Register
    if( [currentElement isEqualToString:@"RegisterResult"])
    {
        elementFound = YES;
    }

}

-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string
{
    //Category
    if (xmlBlock == CATEGORY){
        if ([currentElement isEqualToString: @"Item"]){
            [categoryName appendString:string];
        }
    }

    //Currency
    if (xmlBlock == CURRENCY){
        if ([currentElement isEqualToString: @"CountryName"]){
            [countryName appendString:string];
        }
        else if ([currentElement isEqualToString: @"CurrencyName"]){
            [currencyName appendString:string];
        }
        else if ([currentElement isEqualToString: @"Unit"]){
            [currencyUnit appendString:string];
        }
        else if ([currentElement isEqualToString: @"ShortName"]){
            [shortName appendString:string];
        }
    }

    //Nominal
    if ([currentElement isEqualToString: @"Name"] && xmlBlock == NOMINAL){
        [name appendString:string];
    }
    else if ([currentElement isEqualToString: @"Description"] && xmlBlock == NOMINAL){
        [description appendString:string];
    }
    else if ([currentElement isEqualToString: @"Paid"]){
        [paid appendString:string];
    }

    //Project
    if (xmlBlock == PROJECT) {
        if ([currentElement isEqualToString: @"Name"]){
            [projectName appendString:string];
        }
        else if ([currentElement isEqualToString: @"Description"]){
            [projectDescription appendString:string];
        }
    }

    //Register
    if (xmlBlock == REGISTER && elementFound){
        registerVal = string;
    }
}

//---when the end of element is found---
-(void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
 namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{    
    if ([elementName isEqualToString:@"Item"])
    {
        // save values to an item, then store that item into the array...
        [category setObject:categoryName forKey:@"categoryName"];

        [categories addObject:[category copy]];

        Category *c = [[Category alloc] init];
        c.categoryName = categoryName;
        c.totalValue = @"0.00";
        [appDelegate.categories addObject:c];

        NSLog(@"%d", [appDelegate.categories count]);
    }

    //Currency
    if ([elementName isEqualToString: @"Currency"]) {
        // save values to an item, then store that item into the array...
        [currency setObject:countryName forKey:@"countryName"];
        [currency setObject:currencyName forKey:@"currencyName"];
        [currency setObject:currencyUnit forKey:@"unit"];
        [currency setObject:shortName forKey:@"shortName"];

        [currencies addObject:[currency copy]];

        Currency *c = [[Currency alloc] init];
        c.totalValue = @"0.00";
        c.countryName = countryName;
        c.currencyName = currencyName;
        double myDouble = [currencyUnit doubleValue];
        c.unit = myDouble;
        c.shortName = shortName;

        [appDelegate.currencies addObject:c];

        NSLog(@"%d", [appDelegate.currencies count]);

    }

    //Nominal
    if ([elementName isEqualToString:@"Nominal"])
    {
        // save values to an item, then store that item into the array...
        [nominal setObject:name forKey:@"name"];
        [nominal setObject:description forKey:@"description"];
        [nominal setObject:paid forKey:@"paid"];

        [nominals addObject:[nominal copy]];

        NSLog(@"%d", [nominals count]);

    }

    if ([elementName isEqualToString:@"Project"])
    {
        // save values to an item, then store that item into the array...
        [project setObject:projectName forKey:@"projectName"];
        [project setObject:projectDescription forKey:@"projectDescription"];

        [projects addObject:[project copy]];

        Project *p = [NSEntityDescription
                      insertNewObjectForEntityForName:@"Project"
                      inManagedObjectContext:appDelegate.managedObjectContext];
        [p setValue:projectName forKey:@"name"];
        [p setValue:@"0.00" forKey:@"totalValue"];
        NSError *error;
        if (![appDelegate.managedObjectContext save:&error]) {
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
        }
        [appDelegate.projects addObject:p];

        NSLog(@"%d", [appDelegate.currencies count]);
    }

    if ([elementName isEqualToString:@"RegisterResult"])
    {
        if ([registerVal isEqualToString:@"true"]){
            boolRegister = YES;
        }
        else {
            boolRegister = NO;
        }

        NSLog(@"BOOL = %@", (boolRegister ? @"YES" : @"NO"));

        elementFound = FALSE;
    }
}

残念ながら、NSURLConnectionおよびNSXMLParserデリゲートメソッドは呼び出されていません(すべてがヘッダーファイルにあるはずです)。そして、私はその行を完全に理解しているかどうかわかりません:

[queue waitUntilAllOperationsAreFinished];

これにより、呼び出し元のスレッドがすべての操作が完了するまで待機することはありませんか?NSOperationサブクラス自体の障害が原因で、この行が機能していないように感じますか?

誰かがここで私を助けることができますか?

どうもありがとう、

ジャック

4

2 に答える 2

2

問題は、操作をどのように設定したかです。非並行操作として設定されているため、別のスレッドでmainメソッドを実行してから終了します。デリゲートが呼び出されるまでに、スレッドはなくなります。プーフ。あなたの問題はあなたがスレッドを維持していないということです。ここを参照してください:NSOperation内で非同期NSURLConnectionを実行するにはどうすればよいですか?

于 2012-05-18T16:32:04.147 に答える
0

Joelは、メインスレッドで開始startするメソッドを呼び出す必要があるメソッドで正しいかmain、メソッドIDが呼び出されたスレッドを存続させる必要があります。

于 2012-05-19T07:32:26.420 に答える