簡體   English   中英

NSURLConnection委托方法未被調用

[英]NSURLConnection delegate methods not being called

我正在嘗試使用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

我目前正在使用同步調用,但異步似乎更好,因為在我完成代碼庫后,我將把它實現到iPhone應用程序中,我不能讓我的ui凍結。

使用以下方法responseData = [NSMutableData dataWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]];

我得到了我需要的數據但是使用異步我似乎必須使用委托方法來獲取數據。 我嘗試使用@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];

我繼續搜索相關問題,發現這個答案最有幫助 它引導我使用以下方法。 首先,我在我的界面中聲明了一個名為finished的BOOL屬性,並在我的實現中添加了以下方法,這導致我的委托方法被調用。

while(!finished) {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}

只是一個想法 - 你使用自動引用計數的任何機會,並且在你調用[連接開始]和應該調用委托方法(即,已經收到數據)之間,正在釋放創建NSURLConnection的對象?

有什么東西保持對您用來創建NSURLConnection的對象的引用嗎?

根據其他信息,這似乎是一個可能的原因。 您可能在App Delegate(或您創建的其他類)中有以下代碼。

MyClass *object = [[MyClass alloc] init];
[object grabData];

這很棒 - 它實例化一個對象,然后告訴該對象獲取有問題的數據。 但是,一旦grabData完成(並且在NSURLConnection返回數據之前),對象將被釋放,因為沒有任何東西保留它。 解決這個問題:

  1. 在.h文件(創建對象的位置)中創建一個屬性以保留MyClass的實例。

    @property(強)MyClass *對象;

  2. 合成.m文件中的該屬性

    @synthesize對象;

  3. 而不是僅僅創建您的對象,保持對它的引用:

    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]

這將輸出您需要的數據,所有您需要做的就是不要鎖定您的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
  });
});

建立連接后,請寫下面

[連接開始]; 你的委托方法將被調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM