sos の 作業メモ

プログラミングや英会話学習、マイルや旅行、日常生活など。最近はWebFormなASP.NETのお守りがお仕事です。

日々の生活にhappyをプラスする|ハピタス Gポイント

Objective-Cフレーズブック 第4章

Objective‐Cフレーズブック―使いこなすためのコード&イディオム100+

Objective‐Cフレーズブック―使いこなすためのコード&イディオム100+

前回の続き

第4章 一般的なObjective-Cのパターン

二段階の作成

  • インスタンスを生成する時は +allocと+initの二段階にする(昔は+newを使っていたが、今はほとんど使わないらしい)
  • +allocをオーバーライドして、シングルトンクラスを実装することもある

オブジェクトのコピー

  • オブジェクトのコピーを作る方法を知っているのはオブジェクト自身。NSCopyingプロトコルを実装しているオブジェクトなら-copyWithZoneを送信すればよい

オブジェクトのアーカイブ(永続化)

  • 任意のオブジェクトを永続化するには、NSCodingプロトコルの-initWithCoderと-encodeWithCoderを使う。 引数のNSCoderはデータ表現をカプセル化するクラスで、一般にNSKeyedArchiver。キーと値のペアを格納し、異なる順序で読み戻せる

      - (void)encodeWithCoder: (NSCoder*)aCoder
      {
          if ([aCoder allowsKeyedCoding]) {
              [aCoder encodeInt:integer forKey:@"integer"];
              [aCoder encodeObject:string forKey:@"string"];
          } else {
              [aCoder encodeValueOfObjCType:@encode(int) at:&integer];
              [aCoder encodeObject:string];
          }
      }
    
      - (id)initWithCoder:(NSCoder *)aDecoder
      {
          self = [super init];
          if (self) {
              if ([aDecoder versionForClassName: NSStringFromClass([self class])]) {
                  self = nil;
              }
              if ([aDecoder allowsKeyedCoding]){
                  nteger [aDecoder decodeIntegerForKey:@"integer"];
                  string = [aDecoder decodeObjectForKey:@"string"];
              }else{
                  [aDecoder decodeValueOfObjCType:@encode(int) at:&integer];
                  string = [aDecoder decodeObject];
              }
          }
          return self;
      }
    
  • この様にキー付とキーなしの両方をサポートするのがよい。キーなしはネットワーク上の送信等の一時的なものへの使用が多い

  • -initWithCoder:は、古いバージョンのアーカイブからのロードされる可能性も考慮する
  • スーパークラスがNSCodingに準拠する場合は、スーパークラスのこれらの実装を呼び出すことを忘れないようにする

指定イニシャライザーの作成

  • -initは NSObjectの指定イニシャライザ
  • スーパークラスが指定イニシャライザパターンを使用しているなら、一つのイニシャライザをオーバーライドするだけで済む

シングルトンパターン

  • シングルトンはグローバル変数オブジェクト指向版で、シングルトンクラスはひとつだけインスタンスを持つ
  • +sharedInstanceメッセージに応じてシングルトンインスタンスを返す規約で、多くのクラスで"Instance"の部分がクラス名におきかえられて定義されている(ex: NSApplicationの +sharedApplication等)
  • +sharedInstanceでインスタンスを生成すると、マルチスレッド環境下で競合を発生させる可能性がある。できるだけ+initializeで生成しておくとよい

ファサードの提供

    @interface Control : View
    {
        id cell;
    }
    @end
    @implementation Control
    - (id)selectedCell
    {
        return cell;
    }
    - (BOOL)isEnabled
    {
        return [[self selectedCell] isEnabled];
    }
    - (void)setEnabled:(BOOL)flag
    {
        [[self selectedCell] setEnabled:flag];
        [self setNeedsDisplay: YES];
    }
    @end
  • ファサードパターンはデリゲートの一般的な用途の一つ。パブリックインターフェースで、一つ以上のプライベートかセミプライベートオブジェクトをラップする。1つのオブジェクトが、複数の異なるオブジェクトに機能の一部をデリゲートし、各オブジェクトの動作を組み合わせる

クラスクラスターの作成

実行ループの使用

  • 実行ループは、1つ以上のイベントソースからのデータに応じてコードを実行する、イベント駆動型プログラミングモデルを提供する
  • 実行ループ自体はメモリ管理と関係があり、ループの繰り返し毎に自動解放プールがある

古い仕様の話もあちこちにでてきてウンザリすることもあるけど、パターンの章になって少しおもしろくなった感じです。なるほどと思うようなことも出てくるようになってきました。

次回へ続く