1

私はObjective-Cを学び、BigNerdRanchのObj-Cの本を使って言語に慣れています。それぞれがメソッドを継承する2つのクラスを作成することになっているこの1つの演習に到達するまで、これまでのところすべてが順調に進んでいますdealloc。オブジェクトが実際に割り当て解除されたときに表示する目標。したがって、新しいdeallocは次のようになります

Asset.h

#import <Foundation/Foundation.h>
@class Employee;

@interface Asset : NSObject{
    NSString * label;
    unsigned int resaleValue;
}

@property (strong) NSString * label;
@property unsigned int resaleValue;

@end

Employee.h

#import "Person.h"
@class Asset;

@interface Employee : Person
{
    int employeeID;   
    NSString * lastName;
    Person * spouse;
    NSMutableArray * children;
    NSMutableArray * assets;
}

@property int employeeID;
- (void) addAssetObject: (Asset *) a;
- (unsigned int) valueOfAssets;

@end

実装

@implementation Employee
//omitted
    -(void) dealloc
    {
        NSLog(@"deallocating %@", self);
    }
@end


@implementation Asset
//omitted
    -(void) dealloc
    {
        NSLog(@"deallocating %@", self);
    }
@end

main.m

int main (int argc, const char * argv[])
{

    @autoreleasepool {

        NSMutableArray * employees = [[NSMutableArray alloc] init];
        for(int i = 0; i< 10; i++){
            Employee * person = [[Employee alloc] init];
            [person setWeightInKilos:90+i];
            [person setHeightInMeters:1.8 - i/10.0];
            [person setEmployeeID:i];
            [employees addObject:person];
        }

        for(int i = 0; i< 10; i++){
            Asset * asset = [[Asset alloc] init];
            NSString * currentLabel = [NSString stringWithFormat:@"Laptop %d", i];
            [asset setLabel:currentLabel];
            [asset setResaleValue:i*17];

            NSUInteger * randomIndex = random() % [employees count];
            Employee * randomEmployee = [employees objectAtIndex:randomIndex];

            [randomEmployee addAssetObject:asset];
        }

        NSLog(@"Employees: %@", employees);
        NSLog(@"Giving up ownership of one employee");
        [employees removeObjectAtIndex:5]; // This is supposed to trigger the deallocate method
        NSLog(@"Giving up ownership of array");
        employees = nil;
    }
    return 0;
}

もちろん、それが機能descriptionするように、すでに継承されてい%@ます。しかし、私がそれを実行したとき。Deallocが呼び出されず、オブジェクトの割り当てを解除するプリントアウトが取得されません。ここで何が間違っているのかわかりません。

補足:deallocも[super dealloc]同様に行うべきではありませんか?

4

1 に答える 1

9

コードを読んだことから、自動参照カウント(ARC)を使用していると思います。そうでない場合は、開始する必要があります。(ARCは新しいデフォルトであり、Appleの推奨であり、明らかに未来です。)

循環参照があります。従業員には一連の資産があり、その結果、資産は従業員によって存在し続けます。一方、各資産には、所有者の従業員への強い参照が含まれています。これは、どちらのオブジェクトも解放できないことを意味します。

これを修正するには、参照をアセットから保持している従業員に変換して参照にします。

@interface Asset : NSObject{
    NSString * label;
    __weak Employee * holder;
    unsigned int resaleValue;
}

この修正なし:

  • 従業員は資産をメモリに保持します。
  • 資産は従業員を記憶に留めます。
  • 従業員と資産への他のすべての参照が消えても、それらはお互いを記憶に保持し続けます。

この修正で:

  • 従業員は資産をメモリに保持します。
  • 資産は従業員を記憶に留めません。むしろ、それらには安全なゼロ調整参照が含まれています。
  • 従業員は、他の人が必要としなくなったときに解放されます。
  • ホルダーインスタンス変数は、従業員が解放されたときに「魔法のように」クリアされます。
  • アセットは参照されなくなったため、アセットも通過します。
于 2012-04-24T16:58:45.230 に答える