2017-11-07 5 views
1

私はObj-CからSwiftへの私のアプリケーションの一部を翻訳していました。私は理解できない、またはバイパスできない問題に直面しています。iOS - Obj-C/Swiftコード間のキャストで苦闘

モデルクラス予測

@class City; 

@interface Forecast : ForecastInterface 

@property (nonatomic, retain) City *city; 

@end 

モデルクラスForecast48h

@class City; 

@interface Forecast48h : ForecastInterface 

@property (nonatomic, retain) City *city; 

@end 

モデルのCl:

がこのObjective-Cのクラスを見てみましょう今、あなたは私のCoreDataモデルのプレゼンテーションをお尻の概要

@class City; 

@interface Summary : ForecastInterface 

@property (nonatomic, retain) City *city; 

@end 

し、最終的に

モデルForecastInterface

@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 

[OK]を持っています。

なぜForecastやForecast48hタイプをサマリータイプにキャストできないのか理解したいですか?

この例を見て:

var listForecasts = Array<Any>() 

self.listForecasts = city.bestForecastArray() 

これは、いくつかの予測又はForecast48オブジェクトをフェッチし、NSArrayのを返すために、Objective-Cの方法です。

-(NSArray *)bestForecastArray; 

ここで私は苦労している部分です。

私はlistForecastsをダンプするとき、それはForecastとForecast48hオブジェクトのみを含んでいます。

そして、私は私のセルをロードするとき、私はランタイムエラーがあります。

は、型の値をキャストすることができませんでした「Forecast48h_Forecast48h_」

「概要」に、すべての理由は、この二重のForecast48hの初エラーメッセージを入力しますか?

loadメソッドのプロトタイプ:

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

私は本当にロードセル方式に要約オブジェクトを渡す必要があります。 Objective-Cではこれが受け入れられますが、Swiftでは受け入れられないのはなぜですか?

は、Objective-Cで書かれたワーキングこのコードを見てみましょう:

Summary* aSummary = [_listForecasts objectAtIndex:indexPath.row]; 
[cell setDelegate:self]; 
[cell loadCell:aSummary]; 
return cell; 

これは、Objective-Cで働いていました。

助けが必要ですか?追加情報を躊躇しないでください。プロジェクトは複雑で、説明が難しい私はできるだけシンプルにしようとしました。

EDIT:

@interface Summary (Additions) 

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

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

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

答えて

1

多型は、あなたが常にそのスーパークラス型にオブジェクトをキャストすることができることを意味しますが、2つのオブジェクトが同じスーパークラスから派生タイプを持っている場合、あなたは1からキャストすることはできません別のものにタイプしてください。プロトコルの場合、同じものが有効です。

あなたがどんなフェッチされたオブジェクトがForecastInterfaceプロトコル実装していることを確信しているので、あなたのケースでは、それは、ForecastInterfaceタイプを使用するのに十分だ:

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! 
} 

は、彼らがに対処する必要があることのようにあなたの方法を変更しますForecastInterface の代わりにタイプの概要タイプ。

編集

あなただけ概要クラスにあるメソッドを使用する必要がある場合は、次の2つのソリューションを持っている:(1)ForeCastInterfaceプロトコルでこれらのメソッドを移動したり、(2) 概要にキャストを試してみて、オブジェクトがキャストを強制することなく、タイプ概要で本当にある場合にのみ、メソッドを呼び出します。

var tmpForecast = self.listForecasts[indexPath.row] 
if let summary = tmpForecast as? Summary { 
    ... 
} 
+0

ForecastInterface型からサマリー型に戻すことはできますか? – Balanced

+0

@Balancedオブジェクトが実際にサマリータイプの場合にのみ有効です。オブジェクトの型がForecast48hの場合、キャストは常に失敗します。 Forecast48がSummaryのサブクラスだった場合は成功しますが、これはあなたのケースではありません。 –

+0

私は今、ForecastInterface型を扱うためにloadCellメソッドを変更しました。しかし、このメソッドでは、Summary + Additionsファイルで実装されたSummaryタイプからいくつかの特定のメソッドが本当に必要になります。 – Balanced

関連する問題