gpt4 book ai didi

ios - 当应用 iOS GCD 线程时,xml 的解析停止工作

转载 作者:行者123 更新时间:2023-11-29 13:02:22 25 4
gpt4 key购买 nike

我正在开发一个应用程序,用户可以在其中使用网络服务将数据发送到中央数据库。 Web 服务从中央数据库发回带有主键的 XML 文件,因此应用程序上的本地数据库会使用此主键进行更新。当我不使用 GCD 时,一切正常。一引入线程,我似乎就没有得到要解析的 XML 文件。代码似乎将 XML 发送到 Web 服务,但此后什么也没有发生。我实现线程的方式有问题吗?这是代码示例:

-(void) viewDidLoad
{

dispatch_queue_t saveCentralDB = dispatch_queue_create("Writing Database", NULL);

dispatch_async(saveCentralDB, ^ {


NSLog(@"Created NEW THREAD to send info to CENTRAL DB");


NSString *soapMsg = [NSString stringWithFormat:
@"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
"<soap12:Envelope "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
"xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">"
"<soap12:Body>"
"<InsertPurchase xmlns=\"http://tempuri.org/\">"


"<RequestObject xsi:type = \"SpazaPurchaseRequest\">"

"<PurchaseID>%@</PurchaseID>"
"<RemoteSpazaPurchaseID>%@</RemoteSpazaPurchaseID>"
"<UserID>%d</UserID>"

"<RetailerID>%@</RetailerID>"
"<ItemID>%@</ItemID>"
"<CostPrice>%@</CostPrice>"
"<Longitude>%@</Longitude>"
"<Latitude>%@</Latitude>"
"<DatePurchased>%@</DatePurchased>"
"<Barcode>%@</Barcode>"
"<BasketID>%@</BasketID>"
"</RequestObject>"

"</InsertPurchase>"
"</soap12:Body>"
"</soap12:Envelope>",@"0",pklPurchaseID1,fklUserID,fklRetailerID1,fklItemID1, lCostPrice1, sLongitude1, sLatitude1,dtPurchase1,sBarcode1,fklBasketID1];



//---print of the XML to examine---
NSLog(@"%@", soapMsg);

NSURL *url = [NSURL URLWithString:@"http://www.myapp.com/purchases/ProviderWS.asmx?op=InsertPurchase"];




NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMsg length]];


[req addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[req addValue:msgLength forHTTPHeaderField:@"Content-Length"];
[req setHTTPMethod:@"POST"];
[req setHTTPBody: [soapMsg dataUsingEncoding:NSUTF8StringEncoding]];

conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if (conn)
{
webData = [NSMutableData data];

}


});

}

然后我实现以下方法来处理来自 Web 服务的响应。

/************************Processing the feedback XML returned by webservice*****************/

-(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];




//---prints the XML received---
NSLog(@"%@", theXML);


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

}

然后实现正常的委托(delegate)方法:

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(@"XML Parsing Method: didStartElement");

//This is the first node that we search for. The information we want is contained within this node.
if ([elementname isEqualToString:@"ResponseMessage"])
{
currentCentralDBPurchase = [parsingCentralDBPurchaseXML alloc];

//Flag to indicate that we are within the ResponseMessage node/tag.
isStatus = YES;
}

}



- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(@"XML Parsing Method: foundCharacters");

currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}



- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (isStatus)
{
if ([elementname isEqualToString:@"PurchaseID"])
{
currentCentralDBPurchase.centralPurchaseID = currentNodeContent;
}


if ([elementname isEqualToString:@"RemotePurchaseID"])
{
currentCentralDBPurchase.localPurchaseID = currentNodeContent;
}
}

if ([elementname isEqualToString:@"ResponseMessage"])
{
//Update local database with the PurchaseID from the central database. This is how we will identify records that must still be sent to the central database.


//Now update the local database with purchases that have been sent to central database

// Get the DBAccess object;
DBAccess *dbAccess = [[DBAccess alloc] init];



[dbAccess UpdateCentralPurchaseID: [currentCentralDBPurchase.localPurchaseID integerValue] :[currentCentralDBPurchase.centralPurchaseID integerValue] ];


// Close the database because we are finished with it
[dbAccess closeDatabase];

currentCentralDBPurchase = nil;

//Clear the currentNodeContent node so we are ready to process the next one.
currentNodeContent = nil;


}
}

最佳答案

NSURLConnection initWithRequest: 在这种情况下应该在主线程上调用。

dispatch_async(dispatch_get_main_queue(), ^{
conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if (conn)
{
webData = [NSMutableData data];
}
});

它依赖于 RunLoop,Runloop 自动工作在主线程上。您可以在另一个线程上调用 initWithRequest,但您应该在该线程上执行 RunLoop。然而,在调度队列上有点困难,因此使用主队列有助于解决这种情况。

关于ios - 当应用 iOS GCD 线程时,xml 的解析停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19459204/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com