0

スピン ループがない限り、目的の C アップローダ クラスで問題が発生しています (失敗/成功のデリゲートが呼び出されず、サーバーに着信要求が表示されません)。スピンループで完璧に動作します。

Objective-C は初めてです。セットアップは次のとおりです。メイン アプリは、別の pThread で静的関数 (cppFuncA) を実行する C++ クラス (cppClass) をインスタンス化します。

静的関数 (cppFuncA) は、いくつかのデータを取得してアップロードする目的の C クラス/オブジェクト (UploadFunc) をインスタンス化します。

CppClass {
    static void cppFuncA (...);
} 

cppFuncA(...) {
    UploadFunc* uploader = [[[UploadFunc alloc] retain] init];
    while (condition) {
        ...
        [uploader uploadData:(NSData*)data];
    }
    [uploader release]
}

Uploader.h

@interface UploadFunc : NSObject
{
    bool conditional;
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void) uploadData:(NSData*)data;
@end

Uploader.mm

@implementation UploadFeedback
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    conditional = false;
    [connection release];
    NSLog(@"Connection failed! Error - %@ %@",
          [error localizedDescription],
          [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    conditional = false;
    NSLog(@"Succeeded! Received %d bytes of data",0);
    [connection release];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"Response=%@", response);
}

-(void) uploadData:(NSData*)data
{
    …
    NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:theURL];
    … construct request …

    NSURLConnection* theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

    // Only works if I have this following spin loop
    conditional = true;
    while(conditional) {     
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }
    if (!theConnection) std::cerr << "Connection to feedback failed\n";
}

最後の関数「-(void) uploadData:(NSData*)data」は、私が問題を抱えている場所です。スピンループがないと機能しません。何が起こっているかについてのアイデアはありますか?

NSURLRequest と NSURLConnection に保持を追加したので、リクエストがコピーされていない競合状態ではないと思います。

編集:これらは同様の問題である可能性があるように感じます: NSURLConnection - バックグラウンドスレッドからサーバーへの完了 と非同期要求を待つ方法ですが 、関数が終了して範囲外になった後でも、オブジェクト (UploadFunc) はまだ存在します...

4

1 に答える 1

1

デフォルトモードで実行ループを実行しないでください。フレームワークは、他の実行ループ ソースをデフォルト モードにすることができ、NSURLConnection. 確かに、フレームワークがバックグラウンド スレッドの実行ループで他のソースをスケジュールすることは一般的ではありませんが、確実ではありません。

実行ループの実行は、ビジー ループではありません。データが処理できるよりも速く入ってくる場合を除き、CPU 使用率を急上昇させるべきではありません。ビジーループしているように見えるという事実は、デフォルトモードでスケジュールされた別の実行ループソースがあると私が疑う理由です.

NSURLConnectionをプライベート実行ループ モード (アプリに固有の任意の文字列) でスケジュールし、そのモードで実行ループを実行します。で NSURLConnection を初期化し、最後の引数を-initWithRequest:delegate:startImmediately:渡しNOて、デフォルト モードでのスケジューリングを回避できます。次に-scheduleInRunLoop:forMode:、プライベート モードでスケジュールを設定します。

于 2012-04-10T02:18:27.797 に答える