52の有効なメソッド(18)-可変オブジェクトをできるだけ使用

2058 ワード

  • 設計クラスの場合、属性を十分に活用してデータをカプセル化する.
  • プロパティを使用する場合は、「読み取り専用」と宣言できます.
  • のデフォルトでは、属性は「読み取り可能で書き込み可能」であり、設計されたクラスはすべて「可変」(mutable)である.
  • しかし、一般的には、モデリングするデータは必ずしも変更する必要はありません.したがって、一般的には、公開されたインタフェースはreadOnlyと宣言される.
  • は、クラス内でreadwriteとして再宣言することを実装し、クラス内でパラメータを変更することができる.これにより,クラスの実装コード内部でこれらの属性を設定するしかない.
  • #import 
    
    @interface EOCPerson : NSObject
    
    @property (nonatomic, copy, readonly) NSString *firstName;
    @property (nonatomic, copy, readonly) NSString *lastName;
    @property (nonatomic, strong, readonly) NSSet *friends;
    
    - (id)initWithFirstName:(NSString*)firstName
                andLastName:(NSString*)lastName;
    - (void)addFriend:(EOCPerson*)person;
    - (void)removeFriend:(EOCPerson*)person;
    
    @end
    
    // EOCPerson.m
    #import "EOCPerson.h"
    
    @interface EOCPerson ()
    @property (nonatomic, copy, readwrite) NSString *firstName;
    @property (nonatomic, copy, readwrite) NSString *lastName;
    @end
    
    @implementation EOCPerson {
        NSMutableSet *_internalFriends
    }
    
    - (NSSet*)friends {
        return [_internalFriends copy];
    }
    
    - (void)addFriend:(EOCPerson*)person {
        [_internalFriends addObject:person];
    }
    
    - (void)removeFriend:(EOCPerson*)person {
        [_internalFriends removeObject:person];
    }
    
    - (id)initWithFirstName:(NSString*)firstName
                andLastName:(NSString*)lastName {
        if ((self = [super init])) {
            _firstName = firstName;
            _lastName = lastName;
            _internalFriends = [NSMutableSet new];
        }
        return self;
    }
    
    @end
    
  • readonly修飾語が設定された属性については、依然として「キー値符号化」(Key-Value Coding,KVC)技術によってこれらの属性値を設定し、setValue:forKey:の方法で修正することができる.
  • またはカテゴリ情報照会機能により、対応するインスタンス変数のメモリ内のオフセット量を検出して、対応するインスタンス変数の値を変更する.
  • には、共通APIを迂回して属性を設定する2つの方法が追加されている.しかし、これは破壊であり、問題が発生する可能性があります.だから、できるだけ可変のオブジェクトを書くことをお勧めします.

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