gpt4 book ai didi

Objective-C 将父类(super class)转换为子类

转载 作者:行者123 更新时间:2023-12-04 18:06:52 26 4
gpt4 key购买 nike

我有 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;

最佳答案

一般来说,您应该尝试用多态性替换“instanceof”逻辑。所以而不是:

if (myObject isKindOfClass:[NWStorePackageConsumable class])
//doSomething
else if //etc

. . .尝试确定两个类共有的抽象方法,并在每个子类中创建一个特定的实现。例如:

[storePackage deliver]; //This will be different depending on consumable or not. 

如果您无法做到这一点,则可能表明这两个类不应该真正共享一个共同的祖先。

抽象基类与协议(protocol)与类簇:

  • 当您有一个公共(public)框架时使用抽象基类,其中一些细节将由子类处理。
  • 在您想要创建通用合约的地方使用协议(protocol),但实例之间的实现会非常不同。
  • 在使用抽象基类的相同情况下使用类簇(抽象工厂模式的变体),并且当您还希望该公共(public)类包含决定返回哪个具体实例的逻辑时“幕后”。

调试问题:

您是否试图将基类的实例转换为子类?这是不可能的(在正常情况下 - 你可以做一些 isa 指针调配,但你不想这样做)。您需要预先决定您的类(class)应该是什么实例。基类的目的是向消费者提供一个通用接口(interface),消费者不必关心幕后发生的事情以符合该接口(interface)。

使用调试器,检查您的实例实际上是子类的实例。

关于Objective-C 将父类(super class)转换为子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24500549/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com