Objective-CにおけるExtensionとCategoryの使用


Objective-C 2.0はclass extensionsを追加して2つの問題を解決します.
  • は、オブジェクトがプライベートインターフェースを有し、コンパイラによって検証されることを可能にする.
  • は、公開読み取り専用、プライベート書き込み可能な属性をサポートします.

  • プライベートインタフェース(Private Interface)


    Objective-C 2.0以前は、プライベート関数を定義するには、実装ファイルでPrivate categoryを宣言するのが一般的でした.
    @interface MyClass (Private)  - (id)awesomePrivateMethod; @end
    しかしながら、クラスのプライベートメソッドは、通常、上記のCategoryの方法のように独立した@implementationブロックに実装されるのではなく、クラスの@implementationブロックに実装されることが望ましい.実際、CategoryはObjective-Cのpublic/private限定の不足を補うだけだ.
     
    本当の問題はObjective-CコンパイラがCategoryで宣言した方法が他の場所で実現されると考えているので、コンパイラはそれらが本当に実現されたかどうかを確認しようとしません.つまり,開発者が宣言する方法は実現していない可能性があり,コンパイラにも警告はない.コンパイルは、他の場所や独立したファイルで実現されると考えられます.
     
    class exteionsionを使用すると、宣言されたメソッドと属性の実装がclassの@implementationブロックに配置されます.そうでないと、コンパイラがエラーを報告します.
    // someClass.m 
    @interface someClass () 
    -(void)extend; 
    @end 
     
    @implementation someClass 
    //   
    //   
    -(void)extend { 
        // implement private method here; 
    } 
     
    @end

     

    公有可読、プライベート書き込み可能属性(Publicly-Readable,Privately-Writeable Properties)


    可変(immutable)のデータ構造を実現するには、通常、外部コードがsetterでオブジェクトの状態を変更できないという利点がある.しかし、内部で書き込み可能な属性であることが望ましいかもしれません.Class extensionsは、共通インタフェース(クラスの宣言)では、開発者が属性が読み取り専用であることを宣言し、クラス拡張で書き込み可能であることを宣言することができます.これにより、外部コードの場合、このプロパティは読み取り専用になりますが、内部コードはsetterメソッドを使用できます.
     
    @interface MyClass : NSObject
    @property (retain, readonly) float value;
    @end
     
    //  extension,  .
    @interface MyClass ()
    @property (retain, readwrite) float value;
    @end
    

    似ているように見えるが、実は違う。


    Class extensionは匿名のcategoryと誤解されることが多い.文法は確かに似ています既存のクラスにメソッドとプロパティを追加するために使用できますが、目的と動作は異なります.
     
    参考:Apple Documenation
    原文住所:Minutia on Objective-C Categories and Extensions
    転載は出典を明記してください.http://blog.csdn.net/horkychen