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を作成しているオブジェクトが、[接続開始]を呼び出してからデリゲートメソッドを呼び出す必要がある(つまり、データを受信した)ときに割り当てが解除されている可能性はありますか?

NSURLConnectionの作成に使用しているオブジェクトへの参照を維持するものはありますか?

追加情報に基づくと、これが原因である可能性が高いようです。App Delegate(または作成した別のクラス)に次のようなコードが含まれている可能性があります。

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

これは素晴らしいことです。オブジェクトをインスタンス化してから、そのオブジェクトに問題のデータを取得するように指示します。ただし、grabDataが完了すると(NSURLConnectionがデータを返す前に)、オブジェクトは何も保持されていないため、オブジェクトの割り当てが解除されます。これを修正するには:

  1. MyClassのインスタンスを保持するために、.hファイル(オブジェクトを作成する場所)にプロパティを作成します。

    @property(strong)MyClass * object;

  2. .mファイルでそのプロパティを合成します

    @synthesizeオブジェクト;

  3. オブジェクトを作成するだけでなく、オブジェクトへの参照を保持します。

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

    [myClass grabData];

    self.object = myClass;

これにより、オブジェクトがARCによって割り当て解除されるのを防ぐことができます。

オブジェクトを完全に使い終わったら(NSURLConnectionがデータを返した)、self.object = nilを設定して、その参照を削除できます。

于 2012-06-20T19:45:43.060 に答える
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 に答える