0

小さなRTSプロジェクトには、ボタンのリストがあり、それぞれに建物オブジェクトが割り当てられています。非常に一般的な建物もあれば、非常に特殊なものもあるため、一部の建物をサブクラスとして作成しました。

それぞれが PEHouse オブジェクトを持つボタンのリストを作成すると、すべて正常に動作します。

しかし、これらの PEHouse の 1 つがサブクラス化された 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;
    }

すべてがうまく機能します。次のように、サブセット化された建物のボタンの 1 つだけをスポーンすると:

 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;
}
4

3 に答える 3

1

まず、[GMBuildMenu buttonFromBuilding:...] クラス メソッドのシグネチャは何ですか? あなたのコードによると、次のようになります。

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

ただし、慣例により、そのような名前のメソッドはボタンを返すことになっています。

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

あなたのメソッドが PEHouse オブジェクトで何をするかを知ることは興味深いでしょう。それはそれを強く所有していますか?

于 2012-12-30T16:03:07.957 に答える
0

+[GMBuildMenu buttonFromBuilding:withIndex:inDict:]新しく作成されたボタンを返しますが、その参照はどこにも保存しません。ほとんどのボタンはすぐに割り当て解除されないと言うので、メソッドは新しく作成されたボタンへの参照をどこかに格納する必要があると推測します。

メソッドを見ると、次の行が表示されます。

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

他の行はどこにもbuttonFromBuilding:withIndex:inDict:保存されていないので、新しいボタンへの参照をどこかに保存しているnewと推測します。+[GMButtonMenu addButtonToMenu:withLabel:andShowname:]

ボタンは最初の引数に格納されていると思います。あなたはその議論として渡しdictています。

タワーボタンが予期せず割り当て解除されるこれらの考えられる理由を調査します。

  1. dictを呼び出すとnilになります[GMBuildMenu buttonFromBuilding:[PEHouse newTower] withIndex:1 inDict:dict]

  2. dictnilではありませんが、[GMBuildMenu buttonFromBuilding:[PEHouse newTower] withIndex:1 inDict:dict]返品後すぐに割り当てが解除されます。

于 2012-12-30T22:28:43.610 に答える
0

ここでは、ARCが従う慣習の問題だと思います。

newARC が行うことは、 、allocretaincopyまたはからのすべてをmutableCopy解放し、ファクトリ メソッドを自動解放と見なすことです。

インスタンスを返すクラスメソッドを持つ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];
}

次に、戻り値を何にも割り当てていないため、スコープ外になるとすぐに解放されます。

于 2012-12-30T16:12:56.900 に答える