2011-08-01 27 views
1

私はobjective-cに対して比較的新しいスレッド同期の問題があります。私はユーザーに画像を返そうとしています(ユーザーが提供した画像URLを通じて)。私は別のスレッドでイメージのダウンロードを開始しています。スレッド関数は現在のクラスで宣言され、定義されています。 NSURLConnection方法の問題スレッドが実行なっているがあり、私のイメージのダウンロード機能が働いていない(つまり、何が呼び出されない得ているスレッドと画像のダウンロードを開始するためのマルチスレッドの問題

私のクラスの機能は次のとおりです。

- (NSMutableData*)download:(NSString*)strURL 
{ 
    self.strURLData=strURL; 
    [NSThread detachNewThreadSelector:@selector(threadMethod:) toTarget:[ICacheImageDownloadMgr class] withObject:self]; 
    //Here ICacheImageDownloadMgr is my current class 
    while(!bCompletionFlag) 
    { 
     if(bCompletionFlag)//bCompletionFlag is set to TRUE in NSURLConnection::connectionDidFinishLoading method after successful image download 
     { 
      return currentData; 
     } 
    } 
} 

。ここで私の唯一の動機は、画像のダウンロード処理が完了した後に、ユーザーに、「CURRENTDATA」を返すことです そして、私の現在のクラス(すなわち、ICacheImageDownloadMgr)で宣言されたスレッドの方法は次のとおりです。

+ (void) threadMethod:(ICacheImageDownloadMgr*)param 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 

    if(param.currentData) 
    { 
     [param.currentData release]; 
     param.currentData=nil; 
    } 
    param.currentData = [[NSMutableData alloc]initWithLength:0]; 

    NSURL *myURL = [[NSURL alloc] initWithString:param.strURLData]; 
    NSURLRequest *URLRequest = [NSURLRequest requestWithURL: myURL]; 
    param.urlcon = [[NSURLConnection alloc]initWithRequest:URLRequest delegate:self startImmediately:YES]; 
    [myURL release]; 

    param.dataLock = [[NSLock alloc]init]; 

    while(!param.bCompletionFlag) 
    { 
     if([param.dataLock tryLock]) 
     { 
      if(param.bCompletionFlag)//bCompletionFlag is set to TRUE in NSURLConnection::connectionDidFinishLoading method after successful image download, along with NSLock unlock call 
      { 
       break; 
      } 
     } 
    } 

    [pool release]; 

} 

私がここで間違っていることを教えてください。両方のスレッドがブロックされているようですので、NSURLConnectionメソッドが呼び出されません。再度、前述のように、私の唯一の目的は、 "currentData"をユーザーに返すことです。

おかげで、あなたのコードで

答えて

1

param.urlcon = [[NSURLConnection alloc]initWithRequest:URLRequest delegate:self startImmediately:YES];

あなたが現在進行中の転送を管理できるようにするためにデリゲートメソッドに依存している非同期接続を開始します。あなたはデリゲートメソッドの実装を提供していないので、そこに何が起こっているのかは言えません。

リクエストに関してスレッドを開始しているので、あなたの人生を単純化して同期させることができます私はこれがあなたが最初に目指していたものだと思います)、デリゲートプロトコルに対処する必要はありません。あなたはそのための

+ sendSynchronousRequest:returningResponse:error: 

方法、例えば:

[NSURLConnection sendSynchronousRequest:URLRequest returningResponse:&yourResponse error:&yourError]; 
+0

sendSynchronousRequestを使用していただきありがとうございます。それはまさに私がやろうとしていたものです。私のコードは今働いています。しかし、なぜdidReceiveResponse、didReceiveData、およびconnectionDidFinishLoadingのようなNSURLConnectionデリゲートメソッドの実装が私のコードで呼び出されていなかったのか、私はまだ理解できません。私はtiaで述べたように、メインスレッドのwhileループがアプリケーション自体をブロックしていたと思います。 – XMarshall

+0

スレッド内に実行ループを作成しているはずです...あなたのスレッドでは、応答が処理されないようにしています。http://developer.appleを読むことができます。 com/library/ios /#documentation/Cocoa /概念的/マルチスレッディング/ RunLoopManagement/RunLoopManagement.html – sergio

0

もの

  1. 利用NSOperationの代わりに、スレッドのカップル、さらに良いASIHttpRequestを見て使用することができます。
  2. 新しいスレッドを開始して終了するのを待つのはスレッドの無駄です。あなたがする必要があるのは、リクエスト処理を1つのスレッドで済ませてから、データの処理が終了したときに再度リクエストすることです。
1

申し訳ありませんが、あまりにも多くの場所で間違っています。

  1. あなたは他のスレッドが動作するように少ないCPU時間を持つことになりますので良くないdownload:でタイトwhileループ、メインスレッドが飽和しています。
  2. whileループ内のdownload:は、メインスレッドを実質的にブロックします。これにより、ループが終了するまでUIが応答しなくなります。
  3. ループが終了するという保証はありません。
  4. NSURLConnection起動は既に非同期であるため、スレッドを必要としない可能性があります。
  5. ICacheImageDownloadMgrのプロパティは、retainまたはassignです。私はあなたがメモリ管理を正しく行ったとは思わないし、メモリリークやクラッシュの原因になります。
0

これはNSURLConnectionで動作する方法ではありません。 上記のように、NSURLConnectionは、収集する必要があるレスポンスとデータを返すdelegatesメソッドと連携して動作します。

NSURLConnectionは非同期操作のためにバックグラウンドスレッド自体を作成し、そのデリゲートメソッドをメインスレッドに戻します。したがって、実際にバックグラウンドスレッドを自分で作成する必要はありません。

また、接続がwhileループで終了したことを示すフラグを待つ場合、バックグラウンドの利点はまったくありません。さらに、実行ループに制御を戻さないため、接続が完了するまでビーチボールが適用されます。

関連する問題