一些代码而不是很长的解释。 问题是:
从viewDidLoad
调用时,服务器调用会触发委托方法(connectionDidFinishLoading等...)。但是当从XMLFileFullParsed
调用时,请求将启动到服务器,但不会触发相同的方法。
如果我调用[self loadXMLDatas]
而不是线程,则两个服务器调用都可以正常工作。
为什么?
我从这里开始:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(foundaTag:) name:@"foundaTag" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(XMLFileFullParsed:) name:@"XMLFileFullParsed" object:nil];
self.server = [[ServerCommManager alloc] initWithServer:@"http://someserver/"];
[self.server sendQuestionWithCallIdentifier:@"IDENTIFIER" onPage:@"testpage.php" withParams:nil sendAnswerToObject:self]; // -- This one works
[NSThread detachNewThreadSelector:@selector(loadXMLDatas) toTarget:self withObject:nil];
}
- (void) loadXMLDatas {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Do things, create a XMLparser, start to parse.
[pool release];
}
- (void) XMLFileFullParsed:(NSNotification*)notification {
[self.server sendQuestionWithCallIdentifier:@"IDENTIFIER" onPage:@"testpage.php" withParams:nil sendAnswerToObject:self]; // -- This one doesn't work
}
- (void) doYourJob {
[self doTheJob];
[[NSNotificationCenter defaultCenter] postNotificationName:@"XMLFileFullParsed" object:nil userInfo:nil];
}
- (void) doTheJob:(XMLTag*)tag {
if ([tag.name isEqualToString:@"searchedtag"]) {
theData = extract some datas
[[NSNotificationCenter defaultCenter] postNotificationName:@"foundaTag" object:self userInfo:[NSDictionary dictionaryWithObject:theData forKey:@"data"]];
return;
}
for (XMLTag* aTag in tag.childtags) {
[self doTheJob:aTag];
}
}
- (void) executeRequest {
some init
self.connection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response {
}
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
}
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
}
答案 0 :(得分:0)
从您提供的代码中,通知是从另一个线程发布的,而不是您注册观察者的主线程。
在Apple's Notification Documentation中,它说
在多线程应用程序中,通知始终在发布通知的线程中传递,这可能与观察者注册的线程不同。
你可以做的是将通知移动到它自己的方法中,然后像这样使用performSelectorOnMainThread:
- (void) doTheJob:(XMLTag*)tag {
if ([tag.name isEqualToString:@"searchedtag"]) {
theData = extract some datas
[self performSelectorOnMainThread:@selector(sendNotification:) withObject:theData waitUntilDone:YES];
return;
}
for (XMLTag* aTag in tag.childtags) {
[self doTheJob:aTag];
}
}
- (void)sendNotification:(NSArray *)theData {
[[NSNotificationCenter defaultCenter] postNotificationName:@"foundaTag" object:self userInfo:[NSDictionary dictionaryWithObject:theData forKey:@"data"]];
}