后续的NSURLConnections不触发委托方法 [英] Subsequent NSURLConnections not firing delegate methods

查看:110
本文介绍了后续的NSURLConnections不触发委托方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看过这个问题的答案,看到很多类似的问题,但解决方案似乎并不符合我的情况。我对iOS开发非常新颖,所以任何帮助都不会感激。

I've looked all over for answers to this question and have seen a lot of similar issues but the solutions did not seem to pertain to my situation. I'm very new to iOS development so any help would be appreciated.

目前的应用程序正在根据由XML生成的XML Feed来显示城市中发生的事件他们的网站。我将事件存储在plist中,并在应用加载时明确地检查新事件。目前的流程如下:

The current app is looking to display events happening in a city based on an XML feed being generated by their website. I'm storing the events in a plist and checking for new events explicitly on app load. The current process is as follows:


  • 应用程序启动并使NSURLConnection检查服务器的时间戳并下载。

  • 检查新下载的时间戳与本地时间戳,以查看它是否更大。如果是,它将重写包含plist的文件,并触发需要新事件的通知。

这是第二个NSURLConnection似乎没有起火。回调方法本身会触发,但似乎并不像以后的委托方法一样。

This is where the second NSURLConnection does not seem to fire. The callback method itself fires but it does not seem like the delegate methods fire after.

奇怪的是,如果我同时调用两个连接,而不是一个是另一个的结果,他们都会触发并调用委托方法。

The strange thing is that if I call both connections at the same time, as opposed to one as a result of the other, they both will fire and call the delegate methods.

这里是一些类的代码,其中一些内容被清除了:

Here is the code for some of the classes with some of the guts removed for clarity:

应用程序委托:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

// Set up analytics account

// Set the tab bar controller as the window's root view controller and display.
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];

//Set up listeners for event handling
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(timeStampResponse:) name:@"TimeStampResponse" object:nil];    

//Set app loading screen

//Create new OperationQueue, set ActivityIndicator and run TimeStamp Check
parseQueue = [NSOperationQueue new];    
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[self timeStampCheck];  
return YES;
}
-(void)timeStampCheck {
NSLog(@"Time Stamp Check, Creating Connection");
NSURLRequest *timeStampURLRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:kTimeStampURL]];
self.timeStampConnection = [[NSURLConnectionWithTag alloc] initWithRequest:timeStampURLRequest delegate:self startImmediately:YES tag:1];
}

-(void)newEventsNeeded {
NSLog(@"Event File Doesn't Exists or New File Needed, Creating Connection");
NSURLRequest *feedURLRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:kEventFeedURL]];
self.eventsFeedConnection = [[NSURLConnectionWithTag alloc] initWithRequest:feedURLRequest delegate:self startImmediately:YES tag:0];
}

//Callback from DateStampParser
-(void)timeStampResponse:(NSNotification *)notif {
NSString *response = [[notif userInfo] objectForKey:@"TimeStampResponse"];
if ([response isEqualToString:@"NewEvents"]) {
    [self newEventsNeeded];
    self.appLoadingViewController.loadingLabel.text = @"New Events Found...";
} else if ([response isEqualToString:@"NoNewEvents"]){
    [self allEventsLoaded];
}
}

NSURLConnection Delegate方法

-(void)connection:(NSURLConnectionWithTag *)connection didFailWithError:(NSError *)error {
if (connection.tag == 0) {
    NSLog(@"Connection failed on Event Feed");
} else if (connection.tag == 1) {
    NSLog(@"Connection failed on Time Stamp Check");
}
}

-(void)connection:(NSURLConnectionWithTag *)connection didReceiveResponse:(NSURLResponse *)response{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSLog(@"connection:didRecieveResponse:NSHTTPURLResponse");
if ((([httpResponse statusCode]/100) == 2)) {
    //Handling for eventsFeedConnection
    if (connection.tag == 0) {

        NSLog(@"Connection tag = 0");
        self.eventsData = [NSMutableData data];

    } else if (connection.tag == 1) {

        NSLog(@"Connection tag = 1");
        //NSLog(@"Timestamp connection received response");
        self.timeStampData = [NSMutableData data];

    } 

} else {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Network Error" message:@"No Response from the Server" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
    [alert show];
    [alert release];
}
}

-(void)connection:(NSURLConnectionWithTag *)connection didReceiveData:(NSData *)data{
//Handling for eventsFeedConnection
if (connection.tag == 0) {

    self.appLoadingViewController.loadingLabel.text = @"Downloading Events...";
    [eventsData appendData:data];

} else if (connection.tag == 1) {

    self.appLoadingViewController.loadingLabel.text =@"Checking for New Events...";
    [timeStampData appendData:data];

}   
}

-(void)connectionDidFinishLoading:(NSURLConnectionWithTag *)connection{
//Handling for eventsFeedConnection
if (connection.tag == 0) {

    NSLog(@"EventFeed Connection Finished");
    self.eventsFeedConnection = nil;
    [eventsFeedConnection release];
    ParserOperation *parser = [[ParserOperation alloc] initWithData:self.eventsData];
    [parseQueue addOperation:parser];
    [parser release];
    self.eventsData = nil;
    //[eventCategoryListViewController reenableRefreshButton];

} else if (connection.tag ==1){

    NSLog(@"TimeStamp Connection Finished");
    self.timeStampConnection = nil;
    [timeStampConnection release];
    DateStampParser *parser = [[DateStampParser alloc] initWithData:self.timeStampData];
    [parseQueue addOperation:parser];
    [parser release];
    self.timeStampData = nil;

} 

}

不确定从这个代码可能很明显,或者不是什么问题,但如果需要任何附加代码/澄清我想要完成什么,请让我知道。

Not sure if it may be obvious from just this code or not what the problem is but if any additional code is needed/clarification on what I'm trying to accomplish is needed please let me know.

感谢

为了清楚起见,编辑
只是为了澄清,newEventsNeeded的NSLog触发,但只是委托方法,

edit for clarity Just to clarify, the NSLog from newEventsNeeded fires, but just the delegate methods don't get fired.

推荐答案

确保线程启动 NSURLConnection 有一个循环。 NSURLConnection 的异步回调将调度到调用线程runloop。如果调用线程(在这种情况下,它似乎是一个 NSOperation 队列)没有运行循环,或者如果它不在默认运行循环模式下运行,那么将不会看到任何委托回调。您首次致电 [self timeStampCheck] 在主线程上,所以没关系。您以后的电话来自运行队列,可能没有运行循环。

Make sure the thread starting the NSURLConnections has a runloop. NSURLConnection's asynchronous callbacks are dispatched onto the calling threads runloop. If the calling thread (in this case, it seems to be an NSOperation queue) doesn't have a runloop, or if it's not operating in the default run loop mode, you won't see any delegate callbacks. Your first call to [self timeStampCheck] is on the main thread, so that's fine. Your later calls are from the operation queue, which possibly has no runloop.

文档


委托

连接的委托对象。代理将在加载进度时收到
委托消息。委托
的消息将发送到调用此方法的线程上。要使连接
正常工作,调用线程的运行循环必须以
运行,默认运行循环模式。

The delegate object for the connection. The delegate will receive delegate messages as the load progresses. Messages to the delegate will be sent on the thread that calls this method. For the connection to work correctly, the calling thread’s run loop must be operating in the default run loop mode.

这篇关于后续的NSURLConnections不触发委托方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆