IOS学習の十七:Grand Central Dispatch(GCD)プログラミング基礎

5483 ワード

プログラミングの経験がある人は、基本的にマルチスレッドに触れます.
JavaやAndroidの開発では,多数のバックグラウンドで実行され,非同期メッセージキューは,基本的にマルチスレッドを用いて実現されている.
同様にiosモバイル開発とAndroidでは基本的に似たモデルである.
しかし、多くの場合、アプリケーション開発では、同時イベントを処理したり、新しいサブスレッドを開いたりするのに自分でコードしていないことがわかります.
(一般的な呼び出しsdkはネットワークリクエストを開始しますが、システムは新しいスレッドをデフォルトで処理します).
プログラム全体がほぼMainスレッドで実行されているように見えます.
確かに、コントロールのレイアウトを操作したり、コントロールデータを追加したり、UIオブジェクトの更新をメインスレッドで行ったりする現象です.
処理データを取得するために新しいサブスレッドを開いたのを見ても、UIプライマリ・スレッドに通知することでリフレッシュする必要があります.
もちろんios自体もほとんどの言語と同じようにNSThreadスレッドクラスがあります(javaでこのクラスを使用していることはよく知られています).
これらのシステムは最下位のapiクラスを比較して、私が自分の同時スレッドと操作キューを書くために使用することができます.
Androidを学んだ私たちはHandler、Looperという概念を知っています.Looperは、メインスレッドのメッセージループキューであることを明らかにしました.handlerは、サブスレッドとUIメインスレッドのデータインタラクションに使用されることを一般的に理解しています.
iosのGCD特性を見てみると、彼らの間にはいくつか似ていることが分かった.
1.gcdプログラミングの非同期化の使い方を見てみましょう
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        //           ...
        
        //       
        dispatch_async(dispatch_get_main_queue(), ^{
            //             ,
        });
        
    });

dispatch_asyncは非同期操作を開き、最初のパラメータはgcdキューを指定し、2番目のパラメータは物事を処理するブロックをキューに割り当てる.
dispatch_get_global_Queue(0,0)は、グローバルキューが使用されていることを意味します.
一般的にシステム自体には3つのキューがあります.
global_queue,current_queue、main_queue.
グローバルキューを取得するには、2つのパラメータを受け入れます.1つ目は、私が割り当てた物事ハンドラブロックキューの優先度です.高低とデフォルト、0はデフォルト2は高さ、-2は低
#define	DISPATCH_QUEUE_PRIORITY_HIGH 	 2
#define	DISPATCH_QUEUE_PRIORITY_DEFAULT  0
#define	DISPATCH_QUEUE_PRIORITY_LOW 	(-2)

物事を処理した後、UIマスタースレッドに結果を返すか、リフレッシュする必要があります.同様に、上と同じように、マスタースレッドをキャプチャし、ブロック操作を行います.
//天啊,手贱不注意点到home间,会退后发现没保存~~~写的并行一块内容都没了!!!
二:GCDの同時概念
実はプログラミングでは、同期、非同期、同時、ロックなど、いくつかの概念について言及しています.
急にはっきり言えないような気がすることがあります.
次に、上記の画像のロードでこの3つの概念を理解します.
1同期:
   for (int i = 0 ; i < 10; i++) {
      
         UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
          [myImgV[i] setImage:img];
        
    }

10個のピクチャをロードするとします.私は今、これらのピクチャのリソースアドレスを持っていて、1つの配列に保存しています.
まず、最初の画像を取得する例を示します.
同期実行の概念は、最初の画像を取得した後、
forループを実行した最初の文がimgに戻った後、UIインタフェースのリフレッシュを実行することができます.
最初の文が戻るのに10秒かかると、私のプログラムの応答はずっとここに詰まっているように、他の操作はできません.戻ってくるのを待たなければならない!!
そのため、同期の1つのとても理解しやすい感念は、一歩暗くなることです.
2.非同期
  for (int i = 0 ; i < 10; i++) {
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
        //           ...
         UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
        //       
        dispatch_async(dispatch_get_main_queue(), ^{
            //             ,
              [myImgV[i] setImage:img];
        });
        
    });

このコードを見ると、非同期操作の仮定はまだ10秒かかりますが、全体的には、1枚の画像を実行する時間のロードは10秒程度でしょう.
非同期で鳥は役に立たないようですね.しかし、その中の1つを無視しないでください.黒い糸のコアの1つです.このとき、私たちの画像取得操作はスレッドのキューに置いてあります.
今、私たちは画像のロードを見ても10秒かかりますが、この10秒の間、UIのメインスレッドは操作できます.例えば、インタフェースにボタンがあります.あなたは押すことができます.
上のような同期ではなく、10面の間、私は待つしかなく、何もできません.
非同期のコアコンセプトは、新しいスレッド、メッセージコールバック通知です.
3.並列
上記のコードを例に挙げます.前に強調したように、私たちは1枚の画像のロードしか見ていません.今、コードを最初に見た思考に戻ります.
forサイクルです.実は上のコードの後、私は10個の非同期スレッドを作成しました.
はい、ここで、私たちはこの3つの概念を理解しなければなりません.
同期、実は私の前の例はいくつかの限界を挙げて、この例自体が同期実行を必要としないことを説明して、それからみんなに大きい感じを与えます
同期はプログラミングのタブーのようなもので、実はそうではありません.多くの場合.スレッドで提案されている同期ロックなど、いくつかの制限を行うには同期が必要です.聞いてみると役に立ちますか.
私たちが考えているほどの運用同期ではないかもしれませんが、少なくともこの概念が同じように役に立つことを示しています)
私はやはりさっきのロード画像を例に、同期のメリットをどのように運用するかを簡単に説明します.
もちろん、私は同期の状況をシミュレートしただけです.
私たちが今画像のロードをしていると仮定すると、画像自体はロード前にデフォルトの画像で、私をクリックしてロードし、クリックするとネットワークのロード方法を呼び出し、画像はロード中を表示します.
そして、画像をダブルクリックすると(もちろん、理論的にはロードが終わった後)画像を読み取るネットワーク画像が拡大します.いいでしょう.ここまで表現したいことが考えられるはずです.
全体の流れは、画像をクリックする->ロード->ダブルクリックして表示する必要があります.では、クリック->ロード中(画像の作成者と情報を返す)-』になったら、画像をダブルクリック(前に要求された大きな図のリンクで大きな図を表示する)-』
フルロードは返されます(大きな図のリンクが返されます).この時、画像の大きな図が見えなくなりました.戻る前に操作したので、つまり、
多くの場合、次の動作の操作に前の操作のデータを使用する必要がある場合、ボタンロックなどの同期プログラミングを行います.
次の実行には前の実行が必要だと疑問に思うのですが、最初の例のforループの2番目の文は使うのではないでしょうか.
彼らは同期しなければなりませんね.そう思ったら、偶然ですね.私たちは一緒に行きたいと思っています.
しかし、UI操作を更新するのではなく、他のボタンをクリックする操作を解決するために、前に着いた非同期に注意してください.UIのダウンロードと更新は、同期化されている必要があります.
これは正しいですが、システム自体のリスニングイベントがクリック処理をリスニングし、そのリクエストの後、こちらのロード画像は実際にはイベント実行と見なされます.
イベントという抽象的なユニットは、実は定義可能な広さだからだ.
すなわち、1回のデータ取得と画像充填は、実は1つの画像取得ロードイベントであり、イベントは2つのユニット、ロードと充填を含むと言える.
このイベント全体が他のボタンをクリックしても関係ないので、同期する必要はありません.
そうですね.しかし、もし私たちがこの画像をクリックしたら、さっきダブルクリックできる仮説に戻ります.
ここで私はまた少し無視したかもしれませんが、なぜロードの中で私たちはダブルクリックすることができますか?このような仮定は、画像を取得するのは非同期ですが、次の操作は同期する必要があります.
そのため、人為的な同期ロックが行われました.
はい、話が多すぎて、その時少なくとも私たちは2時を知っていました.
非同期は、どうせ時間がかかる操作によるメインスレッドの詰まりのためかもしれません.
同期は、不要なエラーやトラブルを解決するためです.ここまで来ると、いわゆるスレッドセキュリティを頭の中で連想するかもしれません.
実は同期と同期ロックは、このような不要と不安全な要素を考慮しているはずです.
最後に,非同期と同時関係を簡単に述べる.
実は上記のように非同期はマルチスレッド処理の概念を提供しているだけで、
同時実行は、非同期の大規模な実装に似ています.
例えば、弟で保護費を受け取ることができて、教えて自分に渡すことができて、私はその間に他のことをします.
同時に突然、非同期というのは理にかなっていると思いました.では、私は4つの場所を持っていて、1人の弟が受け取りに行きます.私はまだ他のことをすることができますが、
しかし、弟は4つの場所を走って、私がお金を手に入れるのに必要な時間はやはり私自身が受け取るのと同じですが、私はそんなに苦労する必要はありません.他のこともできます.
そのため、4人の弟を派遣すべきだと思っています.場所ごとに保護費が関係ないからです.(ニューヨークのギャングを見たばかりです~).
従って,非同期はスレッド詰まりを解決し,同時は非同期に基づいて特性イベントに適合する処理時間効率を向上させる.
もちろん、10個のピクチャ自体が互いに関連していない場合は、最後のイベントは、10個のピクチャの総容量値を計算する処理を必要とする.
ではdispatch_を使ってgroup_async.
具体的にはドキュメントを見てみましょう.
全体的に、iosGCDというものを見て、一つはblockプログラミングの特性を熟知させ、iosが提供するGCDの特性をどのように使うかを熟知させたことです.
で行ないます.