在一个小型RTS项目中,我有一个按钮列表,每个按钮都有一个分配给它们的构建对象。有些建筑物非常通用,但其他建筑物非常特殊,因此我将其中的一些建筑物作为子类。
当我制作一个按钮列表时,每个按钮都有一个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;
}
答案 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对象的作用会很有趣。它是否强烈拥有它?
答案 1 :(得分:0)
我认为这是ARC遵循的惯例问题。
ARC做的是释放来自new
,alloc
,retain
,copy
或mutableCopy
的所有内容,并将工厂方法视为自动释放。< / p>
我怀疑使用返回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];
}
然后,由于您没有将返回值分配给任何内容,因此它会在超出范围时立即释放。
答案 2 :(得分: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
作为该参数。
调查这些塔式按钮意外解除分配的可能原因:
dict
时, [GMBuildMenu buttonFromBuilding:[PEHouse newTower] withIndex:1 inDict:dict]
为零。
dict
不是零,但在[GMBuildMenu buttonFromBuilding:[PEHouse newTower] withIndex:1 inDict:dict]
返回后不久就会被取消分配。