サーチ…


自動参照カウント

自動参照カウント(ARC)を使用すると、必要な場所にretainrelease 、およびautoreleaseステートメントが挿入されるので、自分で記述する必要はありません。また、 deallocメソッドをdeallocします。

手動メモリ管理のサンプルプログラムは、ARCで次のようになります。

@interface MyObject : NSObject {
    NSString *_property;
}
@end

@implementation MyObject
@synthesize property = _property;

- (id)initWithProperty:(NSString *)property {
    if (self = [super init]) {
        _property = property;
    }
    return self;
}

- (NSString *)property {
    return property;
}

- (void)setProperty:(NSString *)property {
    _property = property;
}

@end
int main() {
    MyObject *obj = [[MyObject alloc] init];
    
    NSString *value = [[NSString alloc] initWithString:@"value"];
    [obj setProperty:value];

    [obj setProperty:@"value"];
}

deallocメソッドをオーバーライドして、ARCによって処理されないリソースをクリーンアップすることはできます。手動メモリ管理を使用する場合とは異なり、 [super dealloc]は呼び出さない。

-(void)dealloc {
   //clean up
}

強い参照と弱い参照

現代

弱い参照は次のようなものです:

@property (weak) NSString *property;
NSString *__weak variable;

オブジェクトへの弱い参照がある場合は、フードの下で:

  • あなたはそれを保持していません。
  • 割り当てが解除されると、そのすべての参照は自動的にnilに設定されます

オブジェクト参照は、デフォルトで常に強くなります。しかし、あなたは明示的に彼らが強いと指定することができます:

@property (strong) NSString *property;
NSString *__strong variable;

強い参照とは、その参照が存在する間にオブジェクトを保持していることを意味します。

手動メモリ管理

これは、手動メモリ管理で書かれたプログラムの例です。何らかの理由でARCを使用できない限り(32ビットをサポートする必要がある場合など)、このようなコードを書くべきではありません。この例では、 @propertyとsetterの記述方法を示すために@property表記を使用していません。

@interface MyObject : NSObject {
    NSString *_property;
}
@end

@implementation MyObject
@synthesize property = _property;

- (id)initWithProperty:(NSString *)property {
    if (self = [super init]) {
        // Grab a reference to property to make sure it doesn't go away.
        // The reference is released in dealloc.
        _property = [property retain];
    }
    return self;
}

- (NSString *)property {
    return [[property retain] autorelease];
}

- (void)setProperty:(NSString *)property {
    // Retain, then release. So setting it to the same value won't lose the reference.
    [property retain];
    [_property release];
    _property = property;
}

- (void)dealloc {
    [_property release];
    [super dealloc]; // Don't forget!
}

@end
int main() {
    // create object
    // obj is a reference that we need to release
    MyObject *obj = [[MyObject alloc] init];
    
    // We have to release value because we created it.
    NSString *value = [[NSString alloc] initWithString:@"value"];
    [obj setProperty:value];
    [value release];

    // However, string constants never need to be released.
    [obj setProperty:@"value"];
    [obj release];
}

手動参照カウントを使用する場合のメモリ管理ルール

これらのルールは、手動参照カウントを使用する場合にのみ適用されます。

  1. 作成したオブジェクトを所有している

    名前がallocnewcopyまたはmutableCopy始まるメソッドを呼び出す。例えば:

    NSObject *object1 = [[NSObject alloc] init];
    NSObject *object2 = [NSObject new];
    NSObject *object3 = [object2 copy];
    

    つまり、これらのオブジェクトを終了したときにそれらのオブジェクトを解放するのは、自分が担当することを意味します。

  2. retainを使用してオブジェクトの所有権を取得することができます

    オブジェクトの所有権を取得するには、retainメソッドを呼び出します。

    例えば:

    NSObject *object = [NSObject new]; // object already has a retain count of 1
    [object retain]; // retain count is now 2
    

    これはまれな状況でのみ意味があります。

    たとえば、所有者を取得するアクセサまたはinitメソッドを実装する場合は、次のようになります。

    - (void)setStringValue:(NSString *)stringValue {
        [_privateStringValue release]; // Release the old value, you no longer need it
        [stringValue retain]; // You make sure that this object does not get deallocated outside of your scope.
        _privateStringValue = stringValue;
    }
    
  3. あなたがもはやそれを必要としないときは、所有するオブジェクトの所有権を放棄しなければなりません

    NSObject* object = [NSObject new]; // The retain count is now 1
    [object performAction1]; // Now we are done with the object
    [object release]; // Release the object
    
  4. 所有していないオブジェクトの所有権を放棄してはいけません

    つまり、オブジェクトの所有権を取っていないときは、オブジェクトを解放しません。

  5. オートリリープール

    autoreleasepoolは、autoreleaseメッセージを受信したブロック内のすべてのオブジェクトを解放するコードブロックです。

    例:

    @autoreleasepool {
        NSString* string = [NSString stringWithString:@"We don't own this object"];
    }
    

    所有権を持たずに文字列を作成しました。 NSStringメソッドstringWithString:は、文字列が不要になった後に正しく割り当て解除されていることを確認する必要があります。メソッドが返す前に、新しく作成された文字列はautoreleaseメソッドを呼び出すため、文字列の所有権を取得する必要はありません。

    これがstringWithString:実装方法です:

    + (NSString *)stringWithString:(NSString *)string {
        NSString *createdString = [[NSString alloc] initWithString:string];
        [createdString autorelease];
        return createdString;
    }
    

    autoreleasepoolブロックを使用する必要があるのは、所有していないオブジェクトがあることがあります(4つ目のルールは必ずしも適用されません)。

    自動的に参照カウントが自動的にルールを守ります。そうする必要はありません。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow