2012-04-24 68 views
1

我正在學習Objective-C並使用Big Nerd Ranch的Obj-C書來熟悉這門語言。到目前爲止,一切都很順利,直到我完成這一個練習,我應該創建2個班級,每個班級都繼承了dealloc方法。當對象實際被釋放時顯示的目標。因此,新的dealloc看起來像Objective-C: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]以及?

+0

該代碼應該使用ARC還是手動內存管理? – UIAdam 2012-04-24 16:56:42

+1

那麼我可以回答旁註問題:-)既然你好像在使用ARC,那麼[超級dealloc]就會被ARC添加到你的dealloc方法中。 – bas 2012-04-24 16:57:56

回答

9

從閱讀你的代碼,我相信你正在使用自動引用計數(ARC)。如果你不是,你應該開始。 (ARC是新的默認值,Apple的建議,顯然是未來。)

您有一個循環引用:您的員工擁有一系列資產,這會導致員工持有資產。同時,每項資產都對擁有持有人員工提供了強有力的參考。這意味着任何對象都不能被釋放。

要解決這個問題,請將參考資料從資產轉換回持有員工爲參考。

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

沒有此修復程序:

  • 員工持有的資產在內存中。
  • 資產讓員工留在記憶中。
  • 即使對員工和資產的所有其他引用都消失了,他們仍將繼續在內存中保持對方。

通過此修復方法:

  • 員工持有的資產在內存中。
  • 資產不要讓員工在記憶中。相反,它們包含一個安全的歸零參考。
  • 員工將在不再需要時被釋放。
  • 當員工被釋放時,持有者實例變量將被「神奇地」清除。
  • 由於資產不再被引用,它們也會通過。
+0

啊謝謝指出。是的,這應該是新的練習,代碼不應該在那裏(尚) – denniss 2012-04-24 17:06:34

+0

你真的有一本書的ARC版嗎?我很驚訝它已經更新了。 – 2012-04-24 17:10:51

+0

是的,我認爲是。可悲的是我正在使用雪豹+ __ + FML – denniss 2012-04-24 17:18:22

相關問題