NSURLConnection委托方法不被调用
我试图使用NSURLConnection的委托方法。 以下方法目前没有被调用:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection; - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data; - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; //I also want to be able to use self-signed https urls - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace; //I also want to be able to use self-signed https urls
我目前正在使用一个同步调用,但asynchronous似乎更好,因为在我完成代码库后,我要实现它到一个iPhone应用程序,我不能让我的UI冻结。
用下面的方法responseData = [NSMutableData dataWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]];
我得到我需要的数据,但使用asynchronous我似乎我不得不使用委托方法来获取数据。 我试图通过使用@interface myClass : NSObject<NSURLConnectionDelegate>
添加委托@interface myClass : NSObject<NSURLConnectionDelegate>
我打电话给我的方法如下:
-(void)grabData{ NSArray* array = [NSArray arrayWithObjects:@"auth.login",@"user",@"pass", nil]; NSData* packed_array = [array messagePack]; NSURL* url = [NSURL URLWithString:@"https://192.168.1.115:3790/"]; NSMutableURLRequest* request = [[[NSMutableURLRequest alloc]initWithURL:url]retain]; [request setHTTPMethod:@"POST"]; [request setValue:@"RPC Server" forHTTPHeaderField:@"Host"]; [request setValue:@"binary/message-pack" forHTTPHeaderField:@"Content-Type"]; [request setValue:[NSString stringWithFormat:@"%d",[packed_array length]] forHTTPHeaderField:@"Content-Length"]; [request setHTTPBody:packed_array]; //NSHTTPURLResponse *response = nil; NSError *error = nil; NSLog(@"connecting"); NSURLConnection* connection = [[[NSURLConnection alloc]initWithRequest:request delegate:self]retain]; if (connection) { NSLog(@"connection exists"); self.responseData = [[NSMutableData data]retain]; } else { NSLog(@"Connection doesn't exist?"); } NSLog(@"response data: %@",[responseData messagePackParse]); NSLog(@"error: %@",error); }
我尝试了以下内容:
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [connection start];
我继续search相关的问题,发现这个答案最有帮助 。 它导致我使用以下方法。 首先,我在接口中声明了一个名为finished的BOOL属性,并在我的实现中添加了以下方法,这导致我的委托方法被调用。
while(!finished) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; }
只是一个想法,任何机会,你正在使用自动引用计数和创buildNSURLConnection的对象被释放之间的时间,你调用[连接开始]和委托方法应该被调用(即数据已收到)之间?
是否有任何东西保持对你用来创buildNSURLConnection的对象的引用?
根据更多的信息,似乎这是一个可能的原因。 您的App Delegate(或您创build的其他课程)中可能具有以下代码。
MyClass *object = [[MyClass alloc] init]; [object grabData];
这很好,它实例化一个对象,然后告诉该对象抓取有问题的数据。 但是,一旦grabData完成(并在NSURLConnection返回数据之前),对象将被释放,因为没有任何东西持有它。 要解决这个问题:
-
在.h文件(创build对象的位置)中创build一个属性,以保存MyClass的实例。
@property(强)MyClass *对象;
-
在.m文件中合成该属性
@synthesize对象;
-
不要只是创build你的对象,请参考它:
MyClass * myClass = [[MyClass alloc] init];
[myClass grabData];
self.object = myClass;
这将防止你的对象被ARC释放。
当你完全完成对象(你的NSURLConnection已经返回数据),你可以设置self.object = nil来摆脱那个引用。
你可以使用这个:
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest: request delegate:self startImmediately:NO]; [connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [connection start];
如果你遇到麻烦,你可以做我以前做的事情,并使用如下的同步请求:
NSHTTPURLResponse *response = nil; NSError *error = nil; [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]
这将输出你需要的数据,你所需要做的就是不locking你的UI,使用一个块(GCD):
dispatch_queue_t downloadQueue = dispatch_queue_create("download queue", NULL); dispatch_async(downloadQueue, ^{ NSHTTPURLResponse *response = nil; NSError *error = nil; NSData *myData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] dispatch_async(dispatch_get_main_queue(), ^{ // Handle your response data }); });
build立连接后,只写在下面
[连接开始]; 你的委托方法将被调用。