3

質問があります。

最初に NSObject を拡張するオブジェクトを作成し、description メソッドと dealloc メソッドのオーバーライドを提供しました。ここに私の Employee.m ファイルがあります:

@implementation Employee
.....

-(NSString *)description
{
    return [NSString stringWithFormat:@"Employ ID: %d has $%d value of assets", [self     employeeID], [self valueOfAssets]];
}

-(void)dealloc
{   
    NSLog(@"deallocating.. %@", self);
    [super dealloc];
}

私の main.m では、最初に Employee オブジェクトのリストを保持するために NSMutableArray を作成しました。

NSMutableArray *employees = [[NSMutableArray alloc] init];

for (int i =0; i< 10; i++)
{
    // Create an instance of Employee
    Employee *person = [[Employee alloc] init];

    // Give the instance varaible interesting values
    [person setEmployeeID:i];
    [employees addObject: person];
}

そして最後に従業員をnilに設定しました

employees = nil;

各 Employee オブジェクトのメソッドが呼び出されることを期待していたdeallocので、次のようなログが表示されます。

deallocating.. Employ ID 0 has value.....
deallocating.. Employ ID 2 has value.....
....

ただし、ログは表示されdeallocませんでした。メソッドにブレークポイントを設定すると、ブレークポイントに到達しません。

何かご意見は?

4

3 に答える 3

8

いくつかの観察:

  1. person = nil非 ARC コードではオブジェクトを解放しません。ARCコードになります(少なくとも強力な場合)。

  2. ARC では、ローカル オブジェクトが範囲外になると、自動的に解放されます。非 ARC では、スコープ外のオブジェクトは解放されません (また、それらのオブジェクトへの他の参照がない場合は、リークが発生します)。

  3. 変更可能な配列にアイテムを追加すると、アイテムの保持カウントが増加するため、ARC 以外のコードにリリースを含めたとしても、保持カウントがゼロになるまでオブジェクトは解放されません (解放するだけでなく、配列に追加した後の人物オブジェクトだけでなく、配列から削除することもできます。

したがって、これが非 ARC コードであるとすると、次のようになります。

- (void)testInNonArcCode
{
    NSMutableArray *employees = [[NSMutableArray alloc] init]; // employees retain count = +1

    for (int i =0; i< 10; i++)
    {
        //create an instance of Employee
        Employee *person = [[Employee alloc] init]; // person retain count = +1

        //Give the instance varaible interesting values
        [person setEmployeeID:i];
        [employees addObject: person];  // person retain count = +2
        [person release];  // person retain count = +1 (YOU REALLY WANT TO DO THIS OR ELSE OR NON-ARC PROGRAM WILL LEAK)
        // person = nil;   // this does nothing, except clears the local var that's limited to the for loop scope ... it does nothing to reduce the retain count or improve memory management in non-ARC code, thus I have commented it out
    }

    // do whatever you want

    [employees removeAllObjects]; // this will remove all of the person objects and they will have their respective retain counts reduced to 0, and therefore the Employee objects will be released

    [employees release]; // employees array's own retain count reduced to zero (and will now be dealloced, itself)
}

ARC コードでは:

- (void)testInArcCode
{
    NSMutableArray *employees = [[NSMutableArray alloc] init]; // employees retain count = +1

    for (int i =0; i< 10; i++)
    {
        //create an instance of Employee
        Employee *person = [[Employee alloc] init]; // person retain count = +1

        //Give the instance varaible interesting values
        [person setEmployeeID:i];
        [employees addObject: person];  // person retain count = +2

        // person = nil;      // this would reduce person retain count to +1 (but unnecessary in ARC because when person falls out of scope, it will have it's retain count automatically reduced)
    }

    // do whatever you want

    [employees removeAllObjects]; // this will remove all of the person objects and they will have their respective retain counts reduced to 0, and therefore will be released

    // [employees release]; // not permitted in ARC
    // employees = nil;     // this would effectively release employees, but again, not needed, because when it falls out of scope, it will be released anyway
}
于 2012-06-24T04:18:29.087 に答える
3

オブジェクトを解放する適切な方法は、

[employees release];

に設定してnilもメモリは解放されません。

于 2012-06-24T04:04:28.327 に答える
2

の呼び出しが許可されているおかげで、自動参照カウント[super dealloc]を使用していないと推測できます。これは、書くたびにバランシング呼び出しを明示的にペアにする必要があることを意味します。あなたにとって、配列を nil にすると、基本的に従業員のすべてのメモリがリークされました。それらをすべて解放するには、配列をもう一度ループする必要があります。学習しているので、さらに良いことです...できるだけ早くARCコードの記述を開始してください。allocrelease

ARC はまさにこの種の状況のた​​めに作成されたことに注意することが重要かもしれません。それは私たちの脳にとって理にかなっており、最新のツールを使用すれば現実になる可能性があります。

于 2012-06-24T04:06:16.147 に答える