Effective Objective-C 2.0学習ノート

5911 ワード

(1日2件、更新継続)

Objective-Cの起源から

  • OCは、動的バインドメッセージ構造を使用して、実行時にオブジェクトタイプがチェックされます.メッセージを受信した後、どのコードが実行されるかは、コンパイラではなくランタイム環境によって決定されます.
  • C言語をよく勉強する
  • クラスのヘッダファイル(.h)は、できるだけ他のヘッダファイルを参照しないでください.@classで循環参照を解除できます
  • 多用字面量文法
  • NSString *string = @" ";
    NSDictionary *dict = @{@"key":@"value",@"key":@"value"};
    NSArray *array = @[@1,@2,@3];
    
     // 
    int x = 1;
    int y = 2;
    NSNumber *z = @(x*y);
    // copy 
    NSMutableArray *array2=@[@1,@2].mutableCopy;
    

    多用型定数、少用#define

  • 変数はstaticとconstを同時に使用して
  • を宣言する必要があります.
  • constは、彼が修飾した右の内容を修正できないことを意味します.定数定義は通常右から左に解読され、NSString *const string = @" "という意味はstringが定数であり、この定数はポインタであり、このポインタ定数を変更して他のNSStringオブジェクトを指すことを望んでいない.これは要求に合っている.NSStringの前に置くと、ポインタが指す値は定数で、文字列はもともと定数なのでしょう.
  • staticとは、この変数が定義(役割ドメイン)のみを指す.mファイルには、修飾せずに別のコンパイルユニット(OC環境では.mファイル)に同じ名前の変数が宣言されています.コンパイラエラー
  • extern修飾により、ある定数を外部に公開することができる.h中公开声明,.mで定義を実現するには、名前を付けるときにクラス名を接頭辞として区別することに注意しなければならない.

  • 列挙によるステータス、オプション、ステータスコードの表示


    ステータスを表示:
    typedef NS_ENUM(NSUInteger, ) {
        ,
        ,
        ,
    };
    

    表示オプション(複数選択可能)
    typedef NS_OPTIONS(NSUInteger, ) {
         = 0,
         = 1 << 0,
         = 1 << 1,
         = 1 << 2,
    };
    

    ステータスコードを表すときは、switchと結合します.default breakを書かないことを覚えています.このオプション.書いたら、後で列挙要素が追加され、ここに分類され、ヒントはありません.

    属性という概念

  • オブジェクトにカプセル化するデータ
  • property構文で定義する.
  • 「特質」によりデータの格納に必要な正確な意味を定める
  • .
  • プロパティに対応するインスタンス変数を設定する場合は、そのプロパティが宣言した意味に従う必要があります.例:
    copy   NSString  initWithString , [_string copy];
    
  • nonatomic
  • を使用

    オブジェクト内でインスタンス変数にできるだけ直接アクセスする


    3つの原則.
  • オブジェクト内部でデータを読み出す場合は、実力変数で読みます.データを書き込む場合、属性によって書くことで読み取り操作の速度を向上するとともに、属性への書き込み操作を制御することができ、「メモリ管理」の意味
  • を貫くことができる.
  • 初期化メソッドおよびdeallocメソッドでは、常にインスタンス変数によってデータを直接読み書きする必要があります.初期化されるインスタンス変数がスーパークラスに宣言されている場合、このインスタンス変数に直接アクセスできない場合があります.
  • 怠け者で初期化データをロードする場合は、属性によってデータを読み出す必要があります.

  • 対象等同性(仮)

  • 対象の同性を検出するには、isEqual:とhashメソッド
  • を提供してください.
  • 同じオブジェクトは同じハッシュコードを有する必要があるが、2つのハッシュコードが同じオブジェクトは必ずしも同じではない
  • .
  • 盲目的に各属性を検出するのではなく、具体的な需要に応じて検出案
  • を制定しなければならない.
  • hash法を記述する際には、計算速度が速く、ハッシュ符号衝突確率が低いアルゴリズム
  • を用いるべきである.

    実装の詳細をクラスファミリーモードで非表示にする

  • ファミリーモードは、実装の詳細を簡単な共通インタフェースの後ろに隠すことができる
  • システムフレームワークでは、クラス
  • がよく使用される.
  • クラスファミリーの共通抽象ベースクラスから
  • を統合

    既存のクラスで関連オブジェクトを使用してカスタムデータを保存する

  • は、2つのオブジェクトを「関連オブジェクトメカニズム」によって連結することができる
  • .
  • 関連オブジェクトを定義するときにメモリ管理の意味を設定し、属性を定義するときに使用する所有関係と非所有関係
  • を模倣することができる.
  • は、バグの検索が困難になるため、関連オブジェクトを選択する必要があります.

  • 例:
    objc_setAssociatedObject(alert,AlertViewKey,block,BJC_ASSOCIATION_COPY);
    objc_getAssociatedbject(alertView,AlertViewKey);
    

    理解objc_msgSendの役割

  • メッセージは、受信者、選択子、およびパラメータから構成される.あるオブジェクトにメッセージを送信することは、そのオブジェクト上でメソッドを呼び出すことに相当します.
  • がオブジェクトに送信するすべてのメッセージは、対応するメソッドを検出し、そのコードを実行する「動的メッセージ配信システム」によって処理される.

  • メッセージ転送メカニズムの理解


    Message forwarding「メッセージ転送」
  • メッセージ転送の2つの大きなフェーズ
  • まず受信者、所属するクラスに問い合わせ、このselectorを動的に追加して処理できるかどうかを確認します.動的メソッド解析
  • まず、このメッセージを処理できる他のオブジェクトがあるかどうかを受信者に確認してください.「バックアップの受信者」がいなければ、完全なメッセージ転送メカニズムが起動され、ランタイムシステムはメッセージに関するすべての詳細をNSInvocationオブジェクトにカプセル化し、受信者に最後の機会を与え、現在処理されていないメッセージを解決しようとします.

  • オブジェクトが選択子に応答できない場合、メッセージ転送プロセス
  • に進む.
  • 実行期間の動的メソッド解析機能により、あるメソッドを使用する必要がある場合にクラスに追加できる
  • オブジェクトは、解読できないいくつかの選択子を他のオブジェクトに渡して処理することができる.
  • は、上記の2つのステップを経た後も、選択子を処理することができず、完全なメッセージ転送メカニズムを開始する.

  • メソッド・プロビジョニング・テクノロジーでブラックボックス・メソッドをデバッグ

  • は、実行期間において、選択子に対応する方法をクラスに追加または置換して実装することができる.
  • は、従来の方法の代わりに別の実装を用いる「方法プロビジョニング」と呼ばれ、開発者は、この技術を用いて従来の実装に新しい機能
  • を追加する.
  • 一般的には、デバッガの場合にのみ、実行期間にメソッドを変更する必要があります.このメソッドは乱用されてはいけません.

  • 例:
     :
    class_getInstanceMethod(Class aClass,SEL aSelector)
     :
    class_exchangeImplementations(originalMethod,swappedMethod)
    

    クラスオブジェクトの意味を理解する

  • Class自体もObjectIve-Cオブジェクトsuper_classは、このクラスのスーパークラスを定義します.
  • クラスオブジェクトが属するタイプ(すなわちisaポインタが指すタイプ)は、クラスオブジェクト自体が備えるメタデータを表す「メタクラス」と呼ばれる別のクラスである.クラスメソッドはここで定義され、クラスメソッドはクラスオブジェクトのインスタンスメソッドとして理解できます.各クラスにはクラスオブジェクトが1つしかなく、各クラスオブジェクトには関連するメタクラスが1つしかありません.
  • 各インスタンスには、クラスの継承体系を構成するクラスオブジェクトへのポインタがあります.
  • オブジェクトタイプがコンパイル期間中に決定できない場合は、タイプ情報クエリーメソッドを使用して検出する必要があります.
  • は、できるだけタイプ情報照会方法を使用してオブジェクトタイプを決定する.メッセージ転送機能を実装できるオブジェクトがあるため、オブジェクトを直接比較しないでください.

  • インタフェースとAPIの設計

  • あなたの会社、アプリケーション、または両方に関連付けられた名前をクラス名の接頭辞として選択し、すべてのコードでこの接頭辞
  • を使用します.
  • が独自に開発したライブラリには三方ライブラリが用いられており,その中の名前に接頭辞を付けるべきである.

  • 全能初期化方法の提供

  • クラスでは、全能的な初期化方法が提供され、ドキュメントに示されています.他の初期化メソッドは、このメソッドを呼び出す必要があります.
  • 全能初期化方法がスーパークラスと異なる場合は、スーパークラスの対応方法を上書きする必要があります.
  • スーパークラスの初期化方法がサブクラスに適用されない場合は、このスーパークラス方法を上書きし、異常を投げ出すべきである.

  • descriptionメソッドの実装

  • インプリメンテーションdescriptionメソッドは、インスタンスを記述するために意味のある文字列を返す.ここでは、辞書で具体的な内容を格納することがより合理的である.
  • デバッグ時に印刷するには、debugDescriptionメソッドを実装する必要があります.

  • 可変オブジェクトをできるだけ使用

  • 可変オブジェクト
  • をできるだけ作成する.
  • ある属性がオブジェクト内部でのみ変更可能である場合、分類でreadonly属性からreadwrite属性
  • に拡張する.
  • 可変collectionを属性として公開するのではなく、オブジェクト内の可変collectionを変更するための方法を提供する必要があります.

  • 明確で調和のとれたネーミング方法の使用

  • 名標準に従うOCネーミング仕様
  • 方法名言は簡潔で、左から右へ読むと日常用語の中の文のようです
  • メソッド名にサムネイルを使用しないタイプ名
  • プライベートメソッド名に接頭辞を付ける

  • は、プライベートメソッドの名前に接頭辞を付けることで、共通メソッドと容易に区別することができる.
  • は、アップル社に呼び出された
  • を予約するため、下線だけでプライベートメソッドの接頭辞をしないでください.

    Objective-Cエラータイプの理解

  • アプリケーション全体をクラッシュさせる重大なエラーが発生した場合にのみ、例外
  • を使用します.
  • エラーがそれほど深刻でない場合、依頼方法を割り当ててエラーを処理してもよいし、NSErrorオブジェクトにエラー情報を入れて精油出力パラメータを呼び出し者に返すようにしてもよい.