2016-03-21 12 views
1

olmayabilir jenerik türüne [AnyObject] dökme T ihtiva edebilir veya bir dizi olmayabilir.genel bir tür I <code>AnyObject</code> bir dizi bilgisi, ve döküm mi (veya nesneler <em>bir</em>) olur veya bir toplama tipi

ilk denemesi: T bir Array (örneğin T.self == Array<SomeObject>.self) olduğu zaman

class MyClass<T> { 

    func someMethod() -> T? { 

     let anyObjectArray: [AnyObject] = // ... array obtained from Objective-C framework 

     if let objectsAsCollection = anyObjectArray as? T { // Cast always fails 
      return objectsAsCollection 
     } else if let firstObject = anyObjectArray.first as? T { 
      return firstObject 
     } else { 
      return nil 
     } 
    } 
} 

ilk if let döküm başarısız olur.

Böyle bir şey denemek istiyorum, ama bu yazılı şekilde geçerli değil, her nasılsa başka jenerik parametreyi tanıtan içerir:

extension MyClass where T == Array<U> { 

    fun someMethod() -> T? { 

     let anyObjectArray: [AnyObject] = // ... array obtained from Objective-C framework 

     if let objectsAsCollection = anyObjectArray.flatMap({ $0 as? U }) { 
      return objectsAsCollection 
     } else if let firstObject = anyObjectArray.first as? T { 
      return firstObject 
     } else { 
      return nil 
     } 
    } 
} 

Bunu yapmak isteyen nedeni kullanıyorum olmasıdır REST API'sından sonuç almak için bir Object-C çerçevesi (RestKit). Ben bu sonuçlar geri yapıldığı isteğine bağlı olarak belirli bir türü olarak geçer Swift de üzerinde bir tabaka inşa ediyorum, bu yüzden şuna benzer bir Result türü var: Bazen

enum Result<T>: { 
    case Success(T) 
    case Failure(Error) 
} 

T tek olduğunu Nesne, bazen nesnelerin bir dizisidir, ancak Objective-C çerçevesi her zaman sonuçları bir dizi olarak döndürür.

+0

tartışılan hata başka örneği gibi görünüyor. bunların nasıl bir yerli Swift türünde bir diziye döküm yapılacak gibidir: Ör senin '[AnyObject]' 'NSString' yanı sıra' NSNumber' örneklerini tutan diyor? demek, bir genel kullanarak, genel olarak, unutmayın, 't', farklı tipleri yöntemi çağırmak için, izin verir, ancak bu tür her bir çağrı için, 't' tek tip olarak sabitlenir. AnyObject dizisinin her zaman sadece aynı türde nesneler içereceğini kesin olarak biliyor musunuz? – dfri

+0

'AnyObject' dizi teorik olarak herhangi bir tipini içerebilir Amaç-Cı çerçeve dönen @dfri. Ancak, gerçekte Her çağrı için yani kalan API belirli tipte bir dizi döner biliyoruz, 't' 'ya SomeType' veya 'Dizi ' (burada' SomeType' iade edilen nesnenin türüne bağlı olarak değişir sunucu tarafından). – Stuart

+0

ben başkasıyla geçenlerde tam olarak aynı sorunu değerlendiriyordu düşünüyoruz ve NSArray' 'ile' [AnyObject] 'değiştirerek çözüldü. – Sulthan

cevap

3

aşağıdaki sözdizimi çalışacaktır:

class MyClass<T> { 
    func someMethod() -> T? { 
     // let's not convert to [AnyObject] here, keep it as NSArray 
     let anyObjectArray: NSArray = ... 

     // For some reason conversion from [AnyObject] to [T] fails... 
     // However, conversion from NSArray is special 
     if let objectsAsCollection = anyObjectArray as? T { 
      return objectsAsCollection 
     } else if let firstObject = (anyObjectArray as [AnyObject]).first as? T { 
      return firstObject 
     } else { 
      return nil 
     } 
    } 
} 

Ancak, muhtemel bir hata için sadece bir çözümdür. Biz aşağıdakilere probleminizi kaynatabiliriz:

(bildirdi: SR-1054)
class GenericClass<T> { 
    func someMethod() { 
     let anyObjectArray: [AnyObject] = ["test1", "test2", "test3"] 

     print(T) //Array<String> 
     print(T.self == Array<String>.self) //true 

     print(anyObjectArray is [String]) //true 
     print(anyObjectArray is T) //false - BUG 
    } 
} 

let instance = GenericClass<[String]>() 
instance.someMethod() 

bana net bir hata gibi görünüyor

. Aslında bu `AnyObject` dizi tutar nesnelerin kaç _different_ türlerinin bir kısıtlama olmadan zor olacak Type of optionals cannot be inferred correctly in swift 2.2

+0

Ah ne kadar zekice, teşekkürler! Objective-C ile Swift I't ile karşılaştığım arasında yazımın ilk tuhaflığı değil, çözümün bu kadar kolay olmasını beklemiyordum. NSArray’ın kadrosunun neden farklı davrandığını biliyor musunuz? Objective-C’nin dinamik çalışma zamanı ile ilgili bir şey tahmin ediyorum, ancak Swift jeneriklerle nasıl etkileşime girdiğinden emin değilim ... – Stuart

+0

@Stuart Hmmm, nedenini bildiğimi sanıyordum ama yanılıyordum. Bu bir geçici çözüm gibi görünüyor. Biraz daha incelemeye çalışacağım. Sadece bugün genel bir tür için döküm ile bir hata bildiriyorduk yani belki de bu bir hatadır. – Sulthan

+1

@Stuart Sanırım bir hata olduğuna dair bir kanıt var. – Sulthan

İlgili konular