Objective-C は、オブジェクトの作成を割り当てと初期化という明示的な 2 段階のプロセスにするという点で、他の多くのオブジェクト指向言語とは異なります。
Java、C#、C++ などの言語に精通している場合、オブジェクト作成の割り当て部分は初期化から切り離せません。たとえば、Java では次のように記述できます。
class Tree {
// constructor/initialiser
public Tree ()
{
// whatever is needed to initialise a Tree
}
}
...
Tree myTree = new Tree(); // allocate and initalise a tree
Java のnew
式は a にメモリを割り当てTree
、コンストラクタを呼び出してそのメモリを正しく設定します。
上記の言語は、割り当てと初期化が、実際には単一の操作であるオブジェクト作成の 2 つの部分に過ぎないことを認識しています。
Objective-C では、上記の例は次のようになります。
@implementation Tree
// constructor/initialiser
(id) init ()
{
// whatever is needed to initialise a Tree
}
@end
...
Tree *myTree = [[Tree alloc] init]; // allocate and initalise a tree
ここでは、理論的には割り当てと初期化を分離できますが、それはお勧めできません。この理由は[Tree alloc]
、通常、完全に形成された を返さないためです。Tree
一部のメモリを割り当てて としてマークしますが、Tree
が所有するインスタンス変数Tree
、または のスーパー クラスはTree
初期化されません。初期化を行うには、init
呼び出す必要があります。2 つの操作を分離すると、期待どおりに動作しない不完全なオブジェクトが横たわる可能性があります。したがって、それらを分離することはできますが、そうするのは賢明ではないため、Apple のinit
状態に関するドキュメントは次のようになっています。
メッセージは、同じコード行のメッセージinit
と結合されていますalloc
つまり、Apple は、ユーザーが大きな間違いを犯すのを防ぐために、小さな嘘をついているということです。
Objective-C は、作成の単一操作形式も提供します。
Tree *myTree = [Tree new]; // alloc + init
ただし、Java などとは異なり、引数を取るイニシャライザを作成すると、自動的に取得されない引数をnew
取るバージョンが取得されます。それを自分で記述する必要があります (使用するクラス メソッドalloc
および引数を取るイニシャライザとして)。
HTH