我有2个班级:
NWStorePackage
NWStorePackageConsumable
NWStorePackageConsumable是NWStorePackage的子类(专为非消费内容而设计)。
我最近在项目中添加了NWStorePackageConsumable。在整个代码中我都使用NWStorePackage。
我有一个类构造函数来创建适当的实例。
+ (id) storePackageFromStorePackageDictionary: (NSDictionary *) dictionary
根据字典内容返回NWStorePackageConsumable或NWStorePackage。
当某些操作恢复某些与耗材相关的东西时,我会检查包类型(在NWStorePackage中定义的枚举)。如果该类型设置为可消费产品的类型,我将NWStorePackage实例强制转换为NWStorePackageConsumable实例并调用下面的方法。我认为铸件不会成为一个问题,因为我之前正确地制作了它们。
- (id) updateConsumableCount: (int) increase;
这会产生以下错误:
-[NWStorePackage consumableCount]: unrecognized selector sent to instance 0x9c34380
以下是调用方法
的完整代码for(NWStorePackage *storePackage in _storePackagesArray) {
if ([storePackage purchased]) {
NWStorePackageStorage *sps = [NWStorePackageStorage storePackageStorageWithProductIdentifier:storePackage.productIdentifier andIsPurchased:storePackage.purchased];
if ([storePackage packageType] == StorePackageTypeConsumable) {
NWStorePackageConsumable *consumable = (NWStorePackageConsumable *) storePackage;
[sps setConsumableCount: [consumable consumableCount]];
}
[purchases addObject:sps];
}
}
下面的方法是NWStorePackage的构造函数,我不会在NWStorePackageConsumable中覆盖它。
+ (id) initWithContentsOfDictionary: (NSDictionary *) dictionary {
NSLog(@"Initializing NWStorePackage with dictionary content", kLOGLEVEL_STORE);
for (id key in dictionary) {
NSLog(@"Key: %@ :: Value: %@", kLOGLEVEL_STORE, key, [dictionary objectForKey: key]);
}
NWStorePackage *package = [[NWStorePackage alloc] init];
[package setPackageID:[(NSString *)[dictionary objectForKey:@"id"] integerValue]];
[package setTitle:[dictionary objectForKey:@"title"]];
[package setProductIdentifier:[dictionary objectForKey:@"productIdentifier"]];
[package setDescriptionLong:[dictionary objectForKey:@"descriptionLong"]];
[package setDescriptionShort:[dictionary objectForKey:@"descriptionShort"]];
[package setPackageType: (StorePackageType) [[dictionary valueForKey:@"type"] longValue]];
return package;
}
答案 0 :(得分:1)
一般情况下,您应该尝试替换' instanceof'具有多态性的逻辑。所以而不是:
if (myObject isKindOfClass:[NWStorePackageConsumable class])
//doSomething
else if //etc
。 。 。尝试识别两个类共有的抽象方法,并在每个子类中创建一个特定的实现。例如:
[storePackage deliver]; //This will be different depending on consumable or not.
如果你无法做到这一点,那么它可能表明这两个类不应该真正共享一个共同的祖先。
抽象基类vs协议与类集群:
调试问题:
您是否尝试将基类的实例强制转换为子类?这是不可能的(在正常情况下 - 你可以做一些指针调整,但你不想)。你需要决定你的课程应该是前期想要的实例。基类的目的是为消费者提供一个通用接口,不必关心幕后发生的事情以符合该接口。
使用调试器,检查您的实例是实际上是子类的实例。
答案 1 :(得分:0)
将类构造函数更改为此
- (id) initWithContentsOfDictionary: (NSDictionary *) dictionary {
self = [super init];
if (self) {
NSLog(@"Initializing NWStorePackage with dictionary content", kLOGLEVEL_STORE);
for (id key in dictionary) {
NSLog(@"Key: %@ :: Value: %@", kLOGLEVEL_STORE, key, [dictionary objectForKey: key]);
}
[self setPackageID:[(NSString *)[dictionary objectForKey:@"id"] integerValue]];
[self setTitle:[dictionary objectForKey:@"title"]];
[self setProductIdentifier:[dictionary objectForKey:@"productIdentifier"]];
[self setDescriptionLong:[dictionary objectForKey:@"descriptionLong"]];
[self setDescriptionShort:[dictionary objectForKey:@"descriptionShort"]];
[self setPackageType: (StorePackageType) [[dictionary valueForKey:@"type"] longValue]];
}
return self;
}
和便利方法