メモリ管理の概要、ARCの設定に続いて、ARC(Automatic Reference Counting)対応のソースの記述についてです。
メモリの領域を参照数をカウントして、ゼロになった場合に解放するという考え方は同じですが、ARCによって記述が簡単になります。
今まで明示的にretainやreleaseを記述していましたが、以下の記述は全てエラーになります。
・retain
・release
・retainCount
・autorelease
代わりにポインタを管理する変数の修飾子が増えてます。
・__strong
・__weak
・__unsafe_unretained
・__autoreleasing
例えば、以下のような記述をします。
SomeObject * __strong obj;
以下のようにこの変数にポインタを代入した場合、
obj = someObj;
以下と同じ意味で、オブジェクトを所有した事になります。(retainカウントが1増える)
obj = someObj;
[obj retain];
修飾子を省略した場合は「__strong」の扱いなので、実質記述を省略する事ができて、且つ、releaseについては、nilを入れたり、変数がスコープから抜けた際に自動で行われるので、かなりソースがすっきりします。
※メソッドの戻り値の扱いが曖昧ですが、「alloc」「new」「copy」「mutableCopy」で始まる名前のメソッドはretainカウントが1の状態で返して、それ以外のメソッドに関してはautoreleaseしてから返すようです。
それぞれの修飾子の意味は以下の通りです。
■__strong
オブジェクトを所有する(retainする)強い参照。
■__weak
オブジェクトを所有しない(retainカウントを変更しない)弱い参照。
参照しているオブジェクトが解放された場合は自動でnilが入る。
オブジェクトで相互にポインタを保持したい場合など、__strongで保持すると参照が循環してしまって、解放されない状態になるのを回避したい時に使う。
delegate先のオブジェクトの管理に使うのがイメージしやすいと思います。
■__unsafe_unretained
iOS5以前のOSでは__weakが使えないので、古いOSに対応する場合は__unsafe_unretainedを使う。(__weakはコンパイラだけで実現されているのではなく、OSの機能も関係がある。)
参照先のオブジェクトが解放されてもnilが入らないので、参照先のオブジェクトの状態に注意する必要がある。
■__autoreleasing
autoreleaseを呼び出したときと同じ扱い。
autoreleaseに関しては、NSAutoreleasePoolも使えなくなっています。
代わりに以下のブロックを記述できるようになっています。
@autoreleasepool
{
}
ブロックの開始時にpoolが作られて、ブロック終了時にpoolが解放されます。
つまりブロック内でautoreleasepoolに追加されたオブジェクトは、ブロックを出た際にreleaseされることになります。
__strongで定義された変数で管理されているオブジェクトも変数のスコープを出るとreleaseされるので、以下のような記述をした場合はautoreleasepoolのブロックを出た際にリリースされます。
@autoreleasepool
{
NSMutableArray *someObj = [NSMutableArray arrayWithCapacity:1];
}
※arrayWithCapacityはautorelease状態のオブジェクトを返して、__strongのsomeObjに代入されるが、ブロックを出たタイミングでsomeObjのスコープが外れ、且つautoreleasepoolが解放されるので、オブジェクトは解放される。
@autoreleasepoolのブロックは入れ子構造にもできます。
@autoreleasepoolブロックについては、ARCが無効でも、LLVMコンパイラ3.0以降を使っていれば使えます。
ARCのもう一つの大きな違いは、deallocを明示的に呼び出せないという所です。
NSObjectを継承して独自のオブジェクトを作った場合、以下のような記述を行っていました。
-(void)dealloc
{
[super dealloc];
}
この中の[super dealloc];がエラーになります。
ARCでは親クラスのdeallocが呼ばれてからdeallocが呼ばれるので、子クラス側で使っているオブジェクトの後処理だけ書けばOKです。
インスタンス変数にnilを入れて参照を無くすような処理が考えられます。
Objective-CはTool-free bridgeと呼ばれる仕組みで、C言語と共存できるのが特徴ですが、ARCはObjective-Cで使えるものなので、C言語が混ざって来たときは別の記述が必要になってきます。
次回はC言語で書かれたCoreFoundationを使う場合の記述について書きたいと思います。
※iPhoneアプリ開発に関する投稿を今から始めるiPhoneアプリ開発にまとめました。
最近のコメント