2

我正在尝试使用 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];
4

5 回答 5

9

我继续搜索相关问题,发现这个答案最有帮助。它导致我使用以下方法。首先,我在我的接口中声明了一个名为finished 的BOOL 属性,并在我的实现中添加了以下方法,这导致我的委托方法被调用。

while(!finished) {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
于 2012-06-21T21:38:07.290 回答
2

只是一个想法 - 您是否有机会使用自动引用计数并且创建 NSURLConnection 的对象在您调用 [connection start] 和应该调用委托方法(即已收到数据)之间被释放?

是否有任何东西维护对您用于创建 NSURLConnection 的对象的引用?

根据其他信息,这似乎是一个可能的原因。您的 App Delegate(或您创建的另一个类)中可能有如下代码。

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

这很棒——它实例化一个对象,然后告诉该对象获取相关数据。但是,一旦 grabData 完成(并且在 NSURLConnection 返回数据之前),对象将被释放,因为没有任何东西保留它。要解决这个问题:

  1. 在您的 .h 文件(创建对象的位置)中创建一个属性以保留您的 MyClass 实例。

    @property (strong) MyClass *object;

  2. 在 .m 文件中合成该属性

    @synthesize 对象;

  3. 而不是仅仅创建你的对象,持有对它的引用:

    MyClass *myClass = [[MyClass alloc] init];

    [myClass 抓取数据];

    self.object = myClass;

这将防止您的对象被 ARC 释放。

当您完全完成对象(您的 NSURLConnection 已返回数据)时,您可以设置 self.object = nil 以摆脱该引用。

于 2012-06-20T19:45:43.060 回答
1

你可以使用这个:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest: request delegate:self startImmediately:NO];

[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

[connection start];
于 2015-10-07T07:23:30.760 回答
0

如果你遇到问题,你可以做我过去做过的事情,并像这样使用同步请求:

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
  });
});
于 2012-06-20T19:40:00.423 回答
0

建立连接后,只需在下面写

[连接开始];您的委托方法将被调用。

于 2015-06-25T11:06:13.923 回答