gitのリポジトリを移行する方法

今まで利用していたプロジェクトの直下に移動し、originのURLを確認します。

$ git remote -v
origin  git@github.com:nekoxxxx/test.git (fetch)
origin  git@github.com:nekoxxxx/test.git (push)

このoriginのURLを変更します。

リモートリポジトリを変更する

$ git remote set-url origin git@github.com:nekoxxxx-new/test.git

変更出来ているか確認

$ git remote -v
origin  git@github.com:nekoxxxx-new/test.git(fetch)
origin  git@github.com:nekoxxxx-new/test.git (push)

ブロック

ブロックとは

ブロックオブジェクトはObjective-CではなくC言語の機能として実装されており、iOS4.0から利用できます。

ブロックオブジェクトは実行可能なコードと、それが記述時点でのアクセス可能な変数を1つをまるごと囲い込み、後から評価できるようにパックしたものです。

ブロックは他の言語でのクロージャみたいなものですが、このクロージャーという名称も変数などの環境を囲い込むところからきています。また、クロージャーが自分の外部の変数を参照して取り込むことをキャプチャすると言います。

ブロックの要点

  1. ブロックリテラルの本体には、ブロックリテラル自体のローカル変数と仮引数のほかに、そのブロックリテラルが記述された一で参照可能な変数を含めることができます。変数には、外部変数、そのブロックリテラル内のローカル変数があります。
  2. 外部変数や静的変数(static変数)は、ブロック内からも直接アクセス、変更することができます。
  3. ブロック内のローカル変数のうち自動変数(スタック内の変数)は、ブロックリテラルが記述された時点で値が保存されていて、それが参照される仕組みになっています。
    • 従って、元の変数の値が変化しても、ブロックオブジェクトの評価には反映されてません。
    • また、変数の値は参照できますが、変更はできません。(参照可能な自動変数のコピーを持つことはできるが、参照することしかできない)
    • 自動変数が配列だった場合は、コンパイルエラーが発生します。

自動変数とは

ブロックの中で普通に宣言した変数は全て自動変数になっていて、つまり、我々が利用して来たほとんどの 変数は自動変数だった訳です。自動変数の特徴は、ブロックの最初に生成され、ブロックの終りで消滅する点です。つまり、ブロックの中でしか命がないものになります。

ARCで利用するときの危険性

以下に気をつける必要があります。

  • 循環参照
  • 処理中に解放してしまう

対策としては、selfを弱い参照としてキャプチャし、ブロックオブジェクト内で強い参照を使って保持し、処理中にselfが解放されてしまうことを防ぐ。

例)

__weak Manager *weakSelf = self;    //ブロックに渡すselfは循環参照防止のために弱い参照にする
handler.cleanUp = ^{
    Manager *strangSelf = weakSelf; //処理中に開放されないように保持
    if (strongSelf) {
        [strongSelf->logger writeLog];
    }
}

__block修飾子とは

ブロックの要点でも記載しましたが、ブロックオブジェクトは参照可能な自動変数のコピーを持つことはできるが、参照することしかできません。複数のブロックオブジェクトの間で値を共有して、その関係を関係のブロック内だけに局所化できる変数をしてする機能があります。そのような変数には__blockという修飾子を使用します。

NSNotificationとは

概要

Fundationフレームワークには、ある事象が起こったことを、関連のあるところに通知するという機能が提供されています。これを通知といいます。

仕組み

プログラム内には通知センタといようばれるオブジェクトが用意されていて、通知を受け取りたいオブジェクトは、あらかじめ、どんな通知を受け取りたいかを通知センタに登録しておきます。

どんな通知というのは事象の種類ですが、これはあらかじめいくつか用意されていますが、自分で新しい通知を決めることもできます。

通知機能の登場人物

  1. 通知センタ(postされた通知を登録されている2に通知する)
  2. 通知を受け取るオブジェクト(受け取りたい通知を1に登録しておく)
  3. 通知を投げるオブジェクト(通知をpostする)

プロトコル

プロトコルとは

よく使われるプロトコル(protocol)とは、「複数の者が対象となる事項を確実に実行するための手順等について定めたもの。」との意味です。

Objective-Cのプロトコルもそれに由来します。bjective-Cのプロトコルは、オブジェクトの振る舞いを表すメソッドの集合を定義するものです。@protocolという指示子で宣言します。

オブジェクトがこのプロトコルを採用することを、「プロトコルに適合している」といいます。

よくJavaのインターフェースと似たようなものと言われますが、Objective-Cのプロトコルは、インスタンス変数が定義できるJavaのインタフェースと違って、メソッドしか定義できません。

また、Javaのインターフェースは、定義した全てのメソッドをインターフェースを実装するクラスで実装しないといけませんが、Objective-Cのプロトコルでは、プロトコルの実装クラスで実装することを必須・非必須の指定ができます。

例)

@protocol プロトコル名

メソッドの宣言; //実装は必須 (デフォルトは@required)

@required
メソッドの宣言; //実装は必須

@optional
メソッドの宣言; //実装は任意

@end

継承とカテゴリとクラスエクステンション

Objective-Cにおける継承とカテゴリ、クラスエクステンションの特徴についてまとめてみる。

継承

目的

  • 新しいメソッドを追加する
  • 新しいインスタンス変数を追加する

特徴

  • スーパークラスのメソッドを別の定義で置き換えることができる(override)

カテゴリ

目的

  • あるクラスの一部分のメソッドを実現する
  • 相互に関係の深いメソッドをカテゴリのして分類する(実装が依存関係にあるもの、局所的に使われるメソッドや変数をグループ化)
  • メソッド数が多い大規模なクラスを機能によってカテゴリにしてに分ける
  • つまりクラスのサブモジュールとして利用できる

特徴

  • インスタンス変数は宣言できない
  • インタフェース部に宣言できるのはメソッドのみ(カテゴリはメソッドのみを含む)
  • インタフェース部にメソッドの宣言を書き、実装部にその定義を記述する
  • 数の多いメソッドを関係の深いものや用途が似通ったものといった特徴で関連付けてグループ化するものをさす(もともとカテゴリはSmalltalkにあった概念)
  • 本体の周囲に脱着可能なオプション部品が寄せ集められているようなイメージ
@interface クラス名(カテゴリ名)
メソッドの宣言;
@end


@implementation クラス名(カテゴリ名)
メソッドの定義
@end
  • クラスメソッドとインスタンスメソッド両方を書くことが可能

クラスエクステンション

クラスをカテゴリに分類した場合、宣言したすべてのカテゴリが実行ファイル内に揃っているかどうかは隣家はチェックしないので、たとえばMyClass+Local.mをリンクするのを忘れたとしても実行ファイルは何事もなく完了してしまします。しかし、実際にその中のメソッドが呼び出されるとき、エラーが発生し異常終了していまします。

そこで、クラスエクステンションが導入されていて、カテゴリと似ていますが()内にカテゴリ名を指定せず、()だけを書きます。

例)

@interface MyClass ()

- (void)doSomething;

@end

また、カテゴリと違ってインスタンス変数を記述することもできます。
ここで記述したインスタンス変数は、クラス本体のインタフェース部に追加されます。
テストなどで一時的にプライベートな変数に値をセットしたいときなどにも使うことがあります。

@interface MyClass () {
    BOOL flag;
}

- (void)doSomething {
    ・・・・
}

@end

NSObjectクラス

NSObjectクラス

概要

NSObjectは、ほとんどのObjective-Cクラス階層のルートクラスです。
NSObjectを通して、オブジェクトはランタイムシステムの基本インターフェイスを継承し、Objective-Cのオブジェクトして動作します。

ランタイムシステムの機能を提供

Objective-Cは動的な振る舞いを実現するために実行時にランタイムの力を借りています。
ランタイムは、オブジェクトの生成、解放などのメモリ領域の管理や、送信されたメッセージに対応するメソッドの検索などを行ってくれます。

通常であれば、プログラムから直接ランタイムを使うようなことはありません。これらの基本的な機能はルートクラスのNSObjectでメソッドが用意されています。

ルートクラスであるNSObjectを直接的、または間接的に継承しているクラスは、継承された機能を通して、ランタイムシステムの機能を意識することなく利用できるのです。

クラスとインスタンスに関係するメソッドを提供

NSObjectのサブクラスである、あるゆるクラス及びインスタンスで共通して使われるメソッドを提供している。

<参考>

NSObject Class Reference

●クラスの初期化

+ initialize
+ load

●オブジェクトの生成、コピー、解放

+ alloc
+ allocWithZone:
– init
– copy
+ copyWithZone:
– mutableCopy
+ mutableCopyWithZone:
– dealloc
+ new

●クラスの識別

+ class
+ superclass
+ isSubclassOfClass:

●クラス機能のテスト

+ instancesRespondToSelector:

●プロトコルの適合テスト

+ conformsToProtocol:

●メソッドについての情報取得

– methodForSelector:
+ instanceMethodForSelector:
+ instanceMethodSignatureForSelector:
– methodSignatureForSelector:

●オブジェクトの内容記述

+ description

レシーバのクラスの内容を表すNSStringの文字列を返します。(通常はクラス名)

- description

こちらはインスタンスメソッドです。
レシーバのインスタンスオブジェクトの内容を表すNSStringの文字列を返します。
通常はクラスメイトidを表示しますが、サブクラスによって独自の定義がされることに注意です。
例えば、NSStringのインスタンスは、値としてselfを返しますが、NSArrayのインスタンスは
カンマで区切って配列内の要素を列挙した文字列を返します。
そのため、このメソッドの戻り値を頼りにした実装は好ましくありません。

●破棄コンテンツのプロキシサポート

– autoContentAccessingProxy

●メッセージの送信

– performSelector:withObject:afterDelay:
– performSelector:withObject:afterDelay:inModes:
– performSelectorOnMainThread:withObject:waitUntilDone:
– performSelectorOnMainThread:withObject:waitUntilDone:modes:
– performSelector:onThread:withObject:waitUntilDone:
– performSelector:onThread:withObject:waitUntilDone:modes:
– performSelectorInBackground:withObject:
+ cancelPreviousPerformRequestsWithTarget:
+ cancelPreviousPerformRequestsWithTarget:selector:object:

●メッセージの転送

– forwardingTargetForSelector:
– forwardInvocation:

●動的メソッド解決

+ resolveClassMethod:
+ resolveInstanceMethod:

●エラー処理

– doesNotRecognizeSelector:

●アーカイブ

– awakeAfterUsingCoder:
– classForCoder
– classForKeyedArchiver
+ classFallbacksForKeyedArchiver
+ classForKeyedUnarchiver
– replacementObjectForCoder:
– replacementObjectForKeyedArchiver:
+ setVersion:
+ version

●非推奨メソッド

– finalize