Objective c iOS-在Obj-C/Swift代码之间挣扎
我一直在将我的应用程序的一部分从Obj-C翻译成Swift,我面临着一个我无法理解或绕过的问题 看看这个Objective-C类: 模型类预测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
@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 {
...
}