2012-12-30 65 views
0

在一個小型RTS項目中,我有一個按鈕列表,每個按鈕都有一個分配給它們的構建對象。有些建築非常通用,但其他建築非常特殊,我爲此將一些建築物作爲子類。ARC釋放子類NSObject,但不包含自定義NSObjects

當我做鈕釦,他們各自有一個PEHouse對象的列表,一切工作正常。

但是一旦這些PEHouses之一是子類PEHouse時,它會立即釋放,我不明白爲什麼。

按鈕具有這個屬性:

@property (nonatomic, strong) PEHouse *linkedHouse; 

房子有下列值:

@interface PEHouse : NSObject { 
    NSString *title; 
} 
@property (nonatomic) BOOL is_locked; 

我的塔有這樣的設置:當我產卵的列表

#import "PEHouse.h" 

@interface PETower : PEHouse <NSObject> 

-(void)secondAction; 
+ (PETower*)createTower; 

@end 

像這樣的常規對象:

DLog(@"Building menu"); 
    if ([key isEqualToString:@"button_income"]) { 
     [GMBuildMenu buttonFromBuilding:[PEHouse newSawmill] withIndex:1 inDict:dict]; 
     [GMBuildMenu buttonFromBuilding:[PEHouse newQuarry] withIndex:2 inDict:dict]; 
     [GMBuildMenu buttonFromBuilding:[PEHouse newIronMine] withIndex:3 inDict:dict]; 
     [GMBuildMenu buttonFromBuilding:[PEHouse newMiscShop] withIndex:4 inDict:dict]; 
     [GMBuildMenu buttonFromBuilding:[PEHouse newWeaponsShop] withIndex:5 inDict:dict]; 
     [GMBuildMenu buttonFromBuilding:[PEHouse newArmorShop] withIndex:6 inDict:dict]; 
     [GMBuildMenu buttonFromBuilding:[PEHouse newBazaar] withIndex:7 inDict:dict]; 
     [GMBuildMenu buttonFromBuilding:[PEHouse newTreasury] withIndex:8 inDict:dict]; 
     return YES; 
    } 

一切正常。當我釀出這樣的我子集建築按鍵只有一個:

if ([key isEqualToString:@"button_military"]) { 
     [GMBuildMenu buttonFromBuilding:[PEHouse newTower] withIndex:1 inDict:dict]; 
} 

的對象後立即釋放...

有沒有人有一個線索,爲什麼這種分化發生?

更新

的代碼看起來是這樣的:

+(OpenGLButton*)buttonFromBuilding:(PEHouse*)house withIndex:(int)index inDict:(NSMutableDictionary*)dict { 
    OpenGLButton *new = [GMButtonMenu addButtonToMenu:dict withLabel:house.button_art andShowname:house.title]; 
    new.linkedHouse = house; 
    CGRect buttonFrame = CGRectMake(20, ((30)*index), (28*[GMButtonMenu globalGUIScale]), (28*[GMButtonMenu globalGUIScale])); 
    new.location = buttonFrame; 
    new.index = index; 
    new.details = house.desc; 
    return new; 
} 

在PEHouse我們發現:

+ (PETower *)newTower { 
    PETower *new = [PETower createTower]; 
    return new; 
} 


+ (PEHouse *)newSawmill { 
    PEHouse *new = [PEHouse createDefault]; 
    new.title = @"Sawmill"; 

    new.is_large = YES; 
    return new; 
} 
+1

'buttonFromBuilding:withIndex:inDict:'看起來像什麼?按照普通的Cocoa約定,它應該只是返回一個非擁有引用的按鈕,但我明白你用它來做別的事情了嗎? – Tommy

+0

你可以粘貼這兩種方法:'sawMill'和'newTower'? – Levi

+0

按要求添加。 –

回答

1

首先,什麼是[GMBuildMenu buttonFromBuilding的簽名:.. 。]類方法? 根據你的代碼,它看起來是:

+(void)buttonFromBuilding:(PEHouse *)house withIndex:(int)index inDict:(NSDictionary *)dict 

不過,按照慣例,應該返回一個按鈕,命名爲這樣的方法:

+(UIButton *)buttonFromBuilding:(PEHouse *)house withIndex:(int)index inDict:(NSDictionary *)dict 

這將是有趣的,知道你的方法用於PEHouse對象。它強烈擁有它嗎?

+0

向OP –

+0

添加了所需的功能,所以'GMBuildMenu buttonFromBuilding'返回一個按鈕,但是您的「Building菜單」代碼看起來並不像它在做什麼。如果最後沒有任何東西擁有該按鈕,則只要到達結束大括號,它就會立即釋放。 –

+1

該詞典仍然擁有該按鈕,並且在使用普通房屋時一切正常。如果房屋是定製的PEHOUSE版本,那麼這些房屋只能被釋放。 –

0

我認爲這是ARC所遵循的慣例。

ARC做什麼是釋放一切從newallocretaincopymutableCopy到來,考慮到工廠方法爲自動釋放。

我懷疑是有一個類的方法返回一個OpenGLButton實例將ARC插入你的方法結束一個自動呼叫,做這樣的事情

+(OpenGLButton*)buttonFromBuilding:(PEHouse*)house withIndex:(int)index inDict:(NSMutableDictionary*)dict { 
    OpenGLButton *new = [GMButtonMenu addButtonToMenu:dict withLabel:house.button_art andShowname:house.title]; 
    // ... 
    return [new autorelease]; 
} 

然後因爲你並沒有使用返回值任何事情,只要它超出範圍,它就會被釋放。

0

+[GMBuildMenu buttonFromBuilding:withIndex:inDict:]返回新創建的按鈕,但不在任何地方存儲該引用。既然你說大多數的按鈕沒有立即釋放,我推斷這個方法必須在某個地方存儲對新創建按鈕的引用。

望着方法,我看這樣行:其他線路的buttonFromBuilding:withIndex:inDict:new任何地方

OpenGLButton *new = [GMButtonMenu addButtonToMenu:dict withLabel:house.button_art andShowname:house.title]; 

沒有,所以我推斷+[GMButtonMenu addButtonToMenu:withLabel:andShowname:]商店新按鈕的引用的地方。

我想它存儲在第一個參數中的按鈕。您傳遞的是dict作爲該參數。

探討你的塔按鈕,這些可能的原因被意外釋放:

  1. dict是零,當你調用[GMBuildMenu buttonFromBuilding:[PEHouse newTower] withIndex:1 inDict:dict]

  2. dict不是零,但其本身在[GMBuildMenu buttonFromBuilding:[PEHouse newTower] withIndex:1 inDict:dict]返回後不久釋放。