我正在学习使用iOS 5中的新故事板功能获取基本列表视图 - >详细视图基于导航的应用程序。为了消除复杂性,我只是在数组中模拟我的数据。该数组是一个自定义类(“VehicleModel”),具有多个属性和初始化程序。
大多数属性只是NSStrings,但其中一个是指向“VehicleEngineInfo”对象的指针,该对象具有单个属性(“engineType”)和初始化程序:
-(id)initWithType:(NSString*)type {
if(self = [super init]) {
[self setEngineType: type];
}
return self;
}
我有一个更具体的VehicleEngineElectric类,它扩展了VehicleEngineInfo并添加了一个属性(“cellCountMask”)并且有自己的初始化器:
-(id)initWithCellCountMask:(Byte)mask {
if(self = [super initWithType:ENGINETYPE_ELECTRIC]) {
[self setCellCountMask:mask];
}
return self;
}
当我为数据数组创建一个新的“VehicleModel”实例时,我会像这样调用初始化器:
VehicleModel *m1 = [[VehicleModel alloc] initWithName:@"name" Brand:@"brand" Model:@"model" Type:TYPE_CAR Status:STATUS_ACTIVE EngineInfo:[[VehicleEngineElectric alloc] initWithCellCountMask:0x01] Image:IMAGE_CAR];
如果我立即尝试回读engineType属性([[m1 engineInfo] engineType]),它可以正常工作。当我尝试在不同的方法(例如prepareForSegue :)中读取相同的engineType属性时,我得到一个NSInvalidArgumentException,其中包含可爱的“无法识别的选择器发送到实例...”消息。我可以很好地回读VehicleInfo对象上的任何其他属性 - 只有VehicleEngineInfo属性会导致问题。
我的第一个问题是这是一个内存管理问题(保留/释放)但是我启用了ARC,所以不应该这样。当我离开创建它的方法时,为什么engineType属性会丢失?
更新: @property声明看起来像这样......
在VehicleEngineInfo上:
@property (nonatomic, assign) NSString* engineType;
在VehicleEngineElectric:
@property (nonatomic, assign) Byte cellCountMask;
在主要的VehicleModel上:
@property (nonatomic, assign) VehicleEngineInfo* engineInfo;
@property (nonatomic, assign) NSString* name;
@property (nonatomic, assign) NSString* brand;
@property (nonatomic, assign) NSString* model;
@property (nonatomic, assign) NSString* type;
@property (nonatomic, assign) NSString* status;
@property (nonatomic, assign) VehicleEngineInfo* engineInfo;
@property (nonatomic, assign) UIImage* image;
@synthesize语句只有属性的名称,所以没有什么特别的。
错误信息是:
2011-11-14 23:33:42.951 TableTest [15640:fb03] - [__ NSArrayI engineType]:无法识别的选择器发送到实例0x6a89d90 2011-11-14 23:33:42.953 TableTest [15640:fb03] *由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:' - [__ NSArrayI engineType]:无法识别的选择器发送到实例0x6a89d90' * 第一次抛出调用堆栈: (0x129b052 0x174cd0a 0x129cced 0x1201f00 0x1201ce2 0x35ff 0x705e1e 0x3716d9 0x371952 0xbf986d 0x126f966 0x126f407 0x11d27c0 0x11d1db4 0x11d1ccb 0x1f53879 0x1f5393e 0x2e1a9b 0x24b8 0x2415) 终止调用抛出异常当前语言:auto;目前的目标-c
答案 0 :(得分:1)
assign
类型的对象(与标量相对)属性是不常见的。我希望将其视为retain
或copy
。
它看起来是你的engineInfo
属性被释放并且内存被重新分配到某个地方的NSArray
,然后你要查询对象并获得无法识别的选择器错误,因为你的指针现在指向一个完全不同的对象。
答案 1 :(得分:1)
一般来说,
对象使用类型:保留
NSString的类型使用:复制
其他像int,float等(甚至委托)使用 assign
试试@ jrturton的建议,但不确定这是否是造成问题的真正原因。