2016-07-18 7 views
1

iphoneからキーボードから入力したキーワードを使用してデータベースを検索する必要があります。 これまでにキーボードを検索すると停止します。私はバックグラウンドで実行する場合、私は空の配列を見つける。 キーボードの両方が欲しくないので、キーボードが停止せず、配列にデータがいっぱいになるまで待ちます。私はobjective-cを使用しています。マルチスレッド目的-c


dispatch_semaphore_t task = dispatch_semaphore_create(0); 

manager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); 

NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { 
    if (error) { 

    } else { 
     //int i=0; 
     //NSLog(@"%@",responseObject); 

     header=responseObject; 


     dispatch_semaphore_signal(task); 

    } 

}]; 

[dataTask resume]; 


dispatch_semaphore_wait(task, DISPATCH_TIME_FOREVER); 
return header; 
+0

セマフォでメインスレッドをブロックしているようですね。 – holex

答えて

1

あなたは本質的に非同期メソッド、dataTaskWithRequestを撮影した、それ同期(すなわち、それブロックが呼び出されたスレッド)作られています。セマフォのすべてを取り除く。それはとにかく、本当に悪いパターンです。

これは、ネットワークコールのデータをreturnにしたかったためです。あなたはそうしてはいけません。完了ハンドラパターンを使用する必要があります。例えば


、のは、あなたのメソッドは、現在のように見える想像してみましょう:あなたはvoid戻り値の型に変更し、そしてcompletionHandlerパラメータを追加する必要があります

- (id)performRequest:(NSURLRequest *)request { 
    __block id header; 

    manager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); 

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 

    NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { 
     if (error) { 

     } else { 
      header = responseObject; 
     } 
     dispatch_semaphore_signal(semaphore); 
    }]; 

    [dataTask resume]; 

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

    return header; 
} 

- (void)performRequest:(NSURLRequest *)request completionHandler:(void (^)(id _Nullable responseObject, NSError * _Nullable error))completionHandler { 
    manager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); 

    NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { 
     if (error) { 
      completionHandler(nil, error); 
     } else { 
      completionHandler(responseObject, nil); 
     } 
    }]; 

    [dataTask resume]; 
} 

そして、あなたそのように呼びます:

[self performRequest:request completionHandler:^(id responseObject, NSError *error) { 
    // use responseObject and error here 
}]; 

// but not here 
+0

ご返信ありがとうございます、数行のコードを書いてください。私はそれを最大限に活用することができます。 – Manzoor

+0

私はいくつかのコードを追加しましたが、それが明確でない場合は、そのコードの完全なメソッドを示す質問と、そのメソッドの呼び出し方法を示すスニペットを編集する必要があります。 – Rob

+0

多くのありがとうございます。 – Manzoor