GCDマルチスレッド(一)

9892 ワード

GCDを利用して大量の画像をダウンロードしたデモ。
http://blog.csdn.net/tangbinqi_hua/articale/detail/6579843
GCD概要:
http://www.dreamingwish.com/dream-2012/gcd紹介(一)-基本概念とdispatch-queue.
http://blog.csdn.net/liuhongwei123888/article/details/6899366 GCDはロックを使う必要はありませんが、ユーザーのキューを使うことができます。 ],グローバルキューではなく、ロックの代わりに同期機構が完成されます。その後、dispatchusyncを使用することができます。 あるいはdispatch syncは共有データのアクセスコードをパッケージ化します。
    - (id)something
    {
        __block id localSomething;
        dispatch_sync(queue, ^{
            localSomething = [something retain];
        });
        return [localSomething autorelease];
    }

    - (void)setSomething:(id)newSomething
    {
        dispatch_async(queue, ^{
            if(newSomething != something)
            {
                [something release];
                something = [newSomething retain];
                [self updateSomethingCaches];
            }
        });
    }
dispatch uqueueとdispatchの違いと連絡:
http://blog.csdn.net/ericsuper/article/details/6998856
dispatchuusync:指定された調整行列にブロックオブジェクトを提出し、同期して実行します。dispatchusync:指定された調整行列にブロックオブジェクトを提出して、非同期的に実行します。
dispatchuansync()は呼び出したらすぐに戻ります。
dispatch(usync)を呼び出してからblockが実行されてから戻ってきます。dispatch(usync)は現在のスレッドをブロックします。
[NSThread isMainThread] 現在のスレッドがメインスレッドかどうかを判断します。
dispatch queueはオブジェクトであり、タスクを受け付け、先に実行する順番でタスクを実行します。
ispatch queueは、同時またはシリアルであってもよい。
GCDには三つの列があります。
The main queue: メインスレッドと同じ機能です。実際には、メインスレッドでメーンqueueに提出されたジョブが実行されます。main queueは、dispatchugueを呼び出すことができます。メーンqueueはメインスレッドに関連していますので、シリアル列です。・
Global queues: グローバルキューは、同時キューであり、プロセス全体で共有されます。プロセスには、3つのグローバルキューがあります。高、中、低の3つの優先順位の列があります。dispatchuglobal uqueue関数を呼び出して優先度にキューにアクセスできます。ユーザのキュー: ユーザのキュー(GCDはこのようなキューとは呼ばれませんが、このようなキューを表す特定の名前がないので、ユーザのキューと呼びます。)は関数として使われます。  dispatch_queue_create 作成されたキュー。これらの列はシリアルです。だからこそ、同期機構を完成するために使用できます。伝統的なスレッドのmutexに似ています。

  • キューを作成:
    ユーザのキューを使用するには、まず一つを作成します。関数dispatchu ucreateを呼び出すといいです。関数の最初のパラメータはラベルです。これは単にdebugのためです。二つ目のパラメータはサポートされていません。NULLに入ればいいです。
    送信Job:
    ジョブをキューに送るのは簡単です。dispatchusync関数を呼び出して、一つの列と一つのblockに入ります。列はこのblockの実行の順番になると、このblockのコードを実行します。下記の例はバックグラウンドで大きなタスクを実行します。/この方法はblock文法が実行されるまではなく、すぐに戻ってきます。blockはバックグラウンドで実行されます。
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [self goDoSomethingLongAndInvolved];
            NSLog(@"Done doing something long and involved");
    });
    典型的なCocoaプログラムでは、タスク完了時にインターフェースを更新することを望む可能性が高いです。これはメインスレッドでコードを実行する必要があります。このタスクを簡単に完成できます。ネストされたdispatchを使って、外層でバックグラウンドタスクを実行し、内部層でタスクdispatchをmain queueに送ります。コードは以下の通りです。
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [self goDoSomethingLongAndInvolved];
            dispatch_async(dispatch_get_main_queue(), ^{
                [textField setStringValue:@"Done doing something long and involved"];
            });
    });
    同期機構に使用するには、queueは全体のキューではなく、ユーザーのキューでなければなりませんので、usingを使用します。dispatch_queue_create一つを初期化してから使用できます。dispatch_async 
    または  dispatch_sync共有データのアクセスコードをカプセル化します。
     
       

    - (id)something 
    { __block id localSomething;
     dispatch_sync(queue, ^{ localSomething = [something retain]; 
    			}); 
    	return [localSomething autorelease]; 
    }
     - (void)setSomething:(id)newSomething 
    { dispatch_async(queue, ^{
    	 if(newSomething != something) 
    		 {
    				   [something release]; 
    		  something = [newSomething retain]; 
    		[self updateSomethingCaches]; 
    		}   }); 
    }



      dispatch queue , lock 。

     
       
     
       
     
       
     
       
     
       
     
      
     
       //dispatch_get_global_queue()     ,    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),  ^{
            for (int i=0; i<100; i++) {
                float newProgress = [progressView progress] + 0.01;
                //     
                dispatch_async(dispatch_get_main_queue(), ^{
                    progressView.progress = newProgress;
                });
                usleep(1000*100);
            } //for loop
        });//dispatch_async
    

    , , :

    for(id obj in array)
        [self doSomethingIntensiveWith:obj];
     [self doSomethingWith:array];

    GCD dispatch_async , dispatch_sync , , 。


    A: , finish 。

    B: group , finish 。

    A B :A B , finish 。


    dispatch group。 dispatch group block Block dispatch_group_create , dispatch_group_async block dispatch queue, 。 :

    dispatch_queue_t queue = dispatch_get_global_qeueue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    for(id obj in array)
        dispatch_group_async(group, queue, ^{
            [self doSomethingIntensiveWith:obj];
        });
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    dispatch_release(group);
     
    [self doSomethingWith:array];
    , , -doSomethingWith: 。 dispatch_group_async block :
    dispatch_queue_t queue = dispatch_get_global_qeueue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    for(id obj in array)
        dispatch_group_async(group, queue, ^{
            [self doSomethingIntensiveWith:obj];
        });
    dispatch_group_notify(group, queue, ^{
        [self doSomethingWith:array];
    });
    dispatch_release(group);
    すべての が に されるだけでなく、 の も に され、これらの はプログラムの の の を します。-doSomethingWith: , GUI, main queue dispatch_group_notify 。 については、GCDはdispatchuapplyという された を しています。この は のブロックを も び して、 に します。そして、すべての が わるのを っています。 たちが むように。
    dispatch_queue_t queue = dispatch_get_global_qeueue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_apply([array count], queue, ^(size_t index){
            [self doSomethingIntensiveWith:[array objectAtIndex:index]];
        });
        [self doSomethingWith:array];
    これは らしいですが、どうすればいいですか?dispatchuapply には バージョンがありません。しかし、 たちが っているのは のためのAPIです。だから たちはdispatchusync ですべてのコードをバックグラウンドに せばいいです。
    dispatch_queue_t queue = dispatch_get_global_qeueue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        dispatch_apply([array count], queue, ^(size_t index){
            [self doSomethingIntensiveWith:[array objectAtIndex:index]];
        });
        [self doSomethingWith:array];
    });
    dispatchu ugroup uwaitとdispatchu ugrouplifyの い:
    その は のdispatch ugrouuwait(..,.)という を しました。
    dispatchu ugroupufy(group、dispatchu uglobal uqueue(0,0)、^{};

    dispatchu ugroup it
    (グループ、 DISPATCHUTIMEUFOREVER
    )0
    さらに に dispatchurease
    (group)    
    // でgroupが わないと っているのでreleaseですが、creat には な がないのでreleaseが です。releaseを えてテストしてから も えていません。 に えたいです。
    した は と じです。もう ってください。
    dispatchu ugroup it
    (グループ、 
    タイムアウト
    )この 、
    のパラメータは、 ち のグループです。
    つ のパラメータは、 された ち です。
    グループが のグループであるかどうかを っています。タイムアウトの にグループが になったら、0に ります。そうでなければ、 0に ります。タイムアウトが のグループです。
    DISPATCHUTIMEU FOREVERは、グループ のコンテンツが に されるまで しています。
    の の で うもの dispatchu ugrouplay(group、dispatchu uglobal uqueue(0,0)、^{}
    は、グループ のすべてのプログラムブロックが される に される のプログラムブロックを します。