我想在后台进行一些Web服务通信.我使用Sudzc作为httpRequests的处理程序,它的工作原理如下:
SudzcWS *service = [[SudzcWS alloc] init];[service sendOrders:self withXML:@"my xml here" action:@selector(handleOrderSending:)];[service release];
它将一些XML发送到Web服务,并在指定的选择器中处理响应(在这一个中,一个布尔值):
- (voID)handleOrderSending:(ID)value{ //some controls if ([value boolValue] == YES) { //my stuff }}
当我尝试在我的sendOrders:withXML:action:方法上使用Grand Central dispatch时,我注意到没有调用选择器.我相信原因是NSURLConnection委托消息被发送到创建连接的线程但是线程没有那么久,它在方法完成时结束,杀死任何给委托的消息.
问候
EDIT1
[请求发送]方法:
- (voID) send {//dispatch_async(backgroundQueue,^(voID){ // If we don't have a handler,create a default one if(handler == nil) { handler = [[SoapHandler alloc] init]; } // Make sure the network is available if([SoapReachability connectedToNetwork] == NO) { NSError* error = [NSError errorWithDomain:@"SudzC" code:400 userInfo:[NSDictionary dictionaryWithObject:@"The network is not available" forKey:NSLocalizedDescriptionKey]]; [self handleError: error]; } // Make sure we can reach the host if([SoapReachability hostAvailable:url.host] == NO) { NSError* error = [NSError errorWithDomain:@"SudzC" code:410 userInfo:[NSDictionary dictionaryWithObject:@"The host is not available" forKey:NSLocalizedDescriptionKey]]; [self handleError: error]; } // Output the URL if logging is enabled if(logging) { NSLog(@"Loading: %@",url.absoluteString); } // Create the request NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL: url]; if(soapAction != nil) { [request addValue: soapAction forhttpheaderFIEld: @"SOAPAction"]; } if(postData != nil) { [request sethttpMethod: @"POST"]; [request addValue: @"text/xml; charset=utf-8" forhttpheaderFIEld: @"Content-Type"]; [request sethttpBody: [postData dataUsingEnCoding: NSUTF8StringEnCoding]]; if(self.logging) { NSLog(@"%@",postData); } } //dispatch_async(dispatch_get_main_queue(),^(voID){ // Create the connection conn = [[NSURLConnection alloc] initWithRequest: request delegate: self]; if(conn) { NSLog(@" POST DATA %@",receivedData); receivedData = [[NSMutableData data] retain]; NSLog(@" POST DATA %@",receivedData); } else { // We will want to call the onerror method selector here... if(self.handler != nil) { NSError* error = [NSError errorWithDomain:@"SoapRequest" code:404 userInfo: [NSDictionary dictionaryWithObjectsAndKeys: @"Could not create connection",NSLocalizedDescriptionKey,nil]]; [self handleError: error]; } } //}); //finished = NO; // while(!finished) { // // [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; // // }//});}
注释掉的部分是我尝试过的各种东西.最后一部分有效,但我不确定这是不是一个好方法.在类的NURLConnection委托方法中,会发生以下情况:
- (voID)connectionDIDFinishLoading:(NSURLConnection *)connection {NSError* error;if(self.logging == YES) { Nsstring* response = [[Nsstring alloc] initWithData: self.receivedData enCoding: NSUTF8StringEnCoding]; NSLog(@"%@",response); [response release];}CXMLdocument* doc = [[CXMLdocument alloc] initWithData: self.receivedData options: 0 error: &error];if(doc == nil) { [self handleError:error]; return;}ID output = nil;SoapFault* fault = [SoapFault faultWithXMLdocument: doc];if([fault hasFault]) { if(self.action == nil) { [self handleFault: fault]; } else { if(self.handler != nil && [self.handler respondsToSelector: self.action]) { [self.handler performSelector: self.action withObject: fault]; } else { NSLog(@"SOAP Fault: %@",fault); } }} else { CXMLNode* element = [[Soap getNode: [doc rootElement] withname: @"Body"] childAtIndex:0]; if(deserializeto == nil) { output = [Soap deserialize:element]; } else { if([deserializeto respondsToSelector: @selector(initWithNode:)]) { element = [element childAtIndex:0]; output = [deserializeto initWithNode: element]; } else { Nsstring* value = [[[element childAtIndex:0] childAtIndex:0] stringValue]; output = [Soap convert: value toType: deserializeto]; } } if(self.action == nil) { self.action = @selector(onload:); } if(self.handler != nil && [self.handler respondsToSelector: self.action]) { [self.handler performSelector: self.action withObject: output]; } else if(self.defaultHandler != nil && [self.defaultHandler respondsToSelector:@selector(onload:)]) { [self.defaultHandler onload:output]; }}[self.handler release];[doc release];[conn release];conn = nil;[self.receivedData release];}
委托无法发送消息,因为当 – (voID)发送完成时它将死亡.
解决方法 sendOrders的方法定义表明它已经设计为以异步方式执行请求.你应该看看sendOrders的实现:withXML:action:找出是否是这种情况.如果没有使用GCD或SudzcWS的代码看到您的实现,很难说出现了什么问题.尽管有上述警告,但以下内容可能会有所帮助.
看起来您可能在完成之前发布了SudzcWS *服务.
下列:
SudzcWS *service = [[SudzcWS alloc] init];dispatch_async(aQueue,^{ [sevice sendOrders:self withXML:xml action:@selector(handleOrderSending:)];}[service release];
除非SudzcWS保留自己,否则可能会失败.您异步调度块,它将被放入队列,并继续执行该方法.服务被释放并在块执行之前或在服务等待来自Web服务器的响应时被释放.
除非另行指定,否则调用选择器将在调用它的同一线程上执行该选择器.做类似的事情:
SudzcWS *service = [[SudzcWS alloc] init];dispatch_async(aQueue,^{ [sevice sendOrders:self withXML:xml action:@selector(handleOrderSending:)];}- (voID)handleOrderSending:(ID)value{ //some controls //your stuff [service release];}
应该确保sendOrders:方法和handleOrderSending:都在队列aQueue上执行,并且该服务在执行选择器之前不会被释放.
这将要求您保留指向服务的指针,以便handleOrderSending:可以释放它.您可能还想考虑简单地挂在单个SudzcWS实例上,而不是每次想要使用它时创建和释放一个,这应该使您的内存管理更容易,并有助于保持您的对象图紧.
总结以上是内存溢出为你收集整理的ios – 后台线程上的NSURLConnection委托方法全部内容,希望文章能够帮你解决ios – 后台线程上的NSURLConnection委托方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)