Objective c iOS-在Obj-C/Swift代码之间挣扎

Objective c iOS-在Obj-C/Swift代码之间挣扎,objective-c,swift,core-data,casting,swift4,Objective C,Swift,Core Data,Casting,Swift4,我一直在将我的应用程序的一部分从Obj-C翻译成Swift,我面临着一个我无法理解或绕过的问题 看看这个Objective-C类: 模型类预测 @class City; @interface Forecast : ForecastInterface @property (nonatomic, retain) City *city; @end 模型级预测48h @class City; @interface Forecast48h : ForecastInterface @proper

我一直在将我的应用程序的一部分从Obj-C翻译成Swift,我面临着一个我无法理解或绕过的问题

看看这个Objective-C类:

模型类预测

@class City;

@interface Forecast : ForecastInterface

@property (nonatomic, retain) City *city;

@end
模型级预测48h

@class City;

@interface Forecast48h : ForecastInterface

@property (nonatomic, retain) City *city;

@end
模型类摘要

@class City;

@interface Summary : ForecastInterface

@property (nonatomic, retain) City *city;

@end
最后

模型预测界面

@interface ForecastInterface : NSManagedObject

@property (nonatomic, retain) NSDate * date;
@property (nonatomic, retain) NSString * descriptionLabel;
@property (nonatomic, retain) NSString * windDirection;
@property (nonatomic, retain) NSString * seaState;
@property (nonatomic, retain) NSNumber * day;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * probFreeze;
@property (nonatomic, retain) NSString * probSnow;
@property (nonatomic, retain) NSString * probRain;
@property (nonatomic, retain) NSNumber * tempMap;
@property (nonatomic, retain) NSString * tmpMax;
@property (nonatomic, retain) NSNumber * tmpSea;
@property (nonatomic, retain) NSString * tmpMin;
@property (nonatomic, retain) NSString * speedWind;
@property (nonatomic, retain) NSString * endDate;
@property (nonatomic, retain) NSString * startDate;

@end
好的,现在您有了我的CoreData模型的演示

我想了解为什么我不能将Forecast或Forecast48h类型转换为Summary类型

看看这个例子:

@interface Summary (Additions)

+(NSArray*)allSummaryOfCity:(NSManagedObjectContext *)context city:(City*)aCity;

+(NSArray *)arrayInformationsWithSummary:(Summary*)aSummary;

+(NSFetchedResultsController *)fetchControllerForAllSummaryOfCity:(NSManagedObjectContext *)context cityIndicatif:(NSString*)anIndicatifCity;
@end
现在是我挣扎的部分

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as? MyCollectionViewCell
        cell?.layoutIfNeeded()

        var tmpForecast = self.listForecasts[indexPath.row]

        cell?.delegate = self
        cell?.load(tmpForecast as! Summary)

        return cell!
    }
当我转储listForecasts时,它只包含Forecast和Forecast48h对象

当我想加载我的手机时,我有运行时错误:

无法将“Forecast48h\u Forecast48h\u”类型的值强制转换为“Summary”

首先,为什么会在错误消息中键入此双预测48h

加载方法的原型:

-(void)loadCell:(Summary*)weatherSummary;
我确实需要向loadCell方法传递一个Summary对象。 为什么Objective-C接受这一点,而Swift不接受

看看这段代码,它是用Objective-C编写的:

Summary* aSummary = [_listForecasts objectAtIndex:indexPath.row];
[cell setDelegate:self];
[cell loadCell:aSummary];
return cell;
这在Objective-C中起作用

有什么帮助吗?请随时询问更多信息。这个项目很复杂,很难解释,我试着让它尽可能简单

编辑:

@interface Summary (Additions)

+(NSArray*)allSummaryOfCity:(NSManagedObjectContext *)context city:(City*)aCity;

+(NSArray *)arrayInformationsWithSummary:(Summary*)aSummary;

+(NSFetchedResultsController *)fetchControllerForAllSummaryOfCity:(NSManagedObjectContext *)context cityIndicatif:(NSString*)anIndicatifCity;
@end

多态性意味着您始终可以将对象强制转换为其超类类型,但如果两个对象具有派生自同一超类的类型,则无法从一种类型强制转换为另一种类型。在协议的情况下,同样有效

在您的情况下,使用Forecasterface类型就足够了,因为您确信任何获取的对象都实现了Forecasterface协议:

var listForecasts = Array<ForecastInterface>()
self.listForecasts = city.bestForecastArray()

...

-(void)loadCell:(ForecastInterface*)weatherSummary;

...


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as? MyCollectionViewCell
    cell?.layoutIfNeeded()

    // tmpForecast type: ForeCastInterface
    var tmpForecast = self.listForecasts[indexPath.row]

    cell?.delegate = self
    cell?.load(tmpForecast)

    return cell!
}

是否可能在某个时候从Forecasterface类型返回到Summary类型?@仅当对象确实是Summary类型时才平衡。如果对象的类型为Forecast48h,则强制转换将始终失败。如果Forecast48是Summary的一个子类,那么它就会成功,这不是您的情况。我的意思是,为了现在处理ForecastInterface类型,我更改了loadCell方法。但是在这个方法中,我确实需要Summary+Additions文件中实现的Summary类型中的一些特定方法。您需要哪些方法?你能发布Summary+Additions.swift的内容吗?如果你强制施展,如果你有其他对象类型(例如Forecast48h),应用程序将崩溃。
var listForecasts = Array<ForecastInterface>()
self.listForecasts = city.bestForecastArray()

...

-(void)loadCell:(ForecastInterface*)weatherSummary;

...


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as? MyCollectionViewCell
    cell?.layoutIfNeeded()

    // tmpForecast type: ForeCastInterface
    var tmpForecast = self.listForecasts[indexPath.row]

    cell?.delegate = self
    cell?.load(tmpForecast)

    return cell!
}
var tmpForecast = self.listForecasts[indexPath.row]
if let summary = tmpForecast as? Summary {
    ...
}