メモリは正しく管理しないとメモリ消費量が徐々に増えてアプリが強制終了したり、解放済みの領域にアクセスしてクラッシュしたりする
// main.c #include <stdlib.h> int main() { // 整数100個分のメモリを確保する int *p = malloc(100 * sizeof(int)); // 確保した領域を0でクリアする memset(p, 0, 100 * sizeof(int)); // 先頭の値を表示する printf("%d", *p); // メモリを解放する free(p); }
// main.m int main(int argc, char *argv[]) { // 1, 2を要素に持つ配列を初期化する NSArray *p = [[NSArray alloc] initWithObjects:@1, @2, nil]; // %@は文字列はそのままそれ以外のオブジェクトはdescriptionメソッドの返り値を出力する NSLog(@"%@", p); // メモリを解放する [p release]; }
// SomeClass.h @interface SomeClass: NSObject @property (nonatomic, strong) NSObject *object; - (void) someMethod; @end
// SomeClass.m @implementation SomeClass { NSObject *_object; // インスタンス変数の宣言 } @synthesize object = _object; - (void) someMethod { NSLog(@"%@", self.object); } - (void) dealloc { [super dealloc]; [_object release]; // retainCount -1 } @end
// SomeClass.m @implementation SomeClass - (NSObject*) object { return _object; } @end
@synthesize
@property
// SomeClass.m // @property (nonatomic, strong) NSObject *object; - (void) setObject:(NSObject*)object { if (_object != object) { [_object release]; // retainCount -1 _object = [object retain]; // retainCount +1 } }
// main.m int main(int argc, char *argv[]) { SomeClass *someClass = [[SomeClass alloc] init]; NSObject *object = [[NSObject alloc] init]; // [object retainCount] = 1 someClass.object = object; // [object retainCount] = 2 [object release]; // [object retainCount] = 1 [someClass someMethod]; [someClass release]; // [object retainCount] = 0 }
// main.m int main(int argc, char *argv[]) { @autoreleasepool { SomeClass *someClass = [[[SomeClass alloc] init] autorelease]; NSObject *object = [[[NSObject alloc] init] autorelease]; someClass.object = object; [someClass someMethod]; } }
autorelease
release
retain
dealloc
// SomeClass.m // @property (nonatomic, strong) NSObject *object; - (void) setObject:(NSObject*)object { if (_object != object) { _object = object; } } - (void) dealloc { // [super dealloc]; }
// SomeClass.swift class SomeClass: NSObject { var object: NSObject func someMethod() { print("\(self.object)"); } }
// main.swift let someClass = SomeClass() someClass.object = NSObject() someClass.someMethod()
class A { var b: B? = nil } class B { var a: A? = nil } class C { func someMethod() { let a = A() // a=1, b=0 let b = B() // a=1, b=1 a.b = b // a=1, b=2 b.a = a // a=2, b=2 } // a=1, b=1 }
class A { var b: B? = nil } class B { weak var a: A? = nil } class C { func someMethod() { let a = A() // a=1, b=0 let b = B() // a=1, b=1 a.b = b // a=1, b=2 b.a = a // a=1, b=2 } // a=0, b=1 -> a=0, b=0 }
class B { public typealias Completion = () -> () var completion: Completion init(completion: @escaping Completion) { self.completion = completion } func async() { DispatchQueue.main.asyncAfter(deadline: .now() + 3.0, execute: { () in self.completion() self.completion = nil }) } }
class A { var b: B? = nil } class C { func someMethod() { let a = A() // a=1, b=0 let b = B(completion: { print("\(a.message)") // a=2, b=1 }) a.b = b // a=2, b=2 b.async() } // a=1, b=1 -> 3s -> a=0, b=1 -> a=0, b=0 }