2015-02-15 14 views
6

Kodumda meraklı görünen ve bu davranış için açık bir açıklama olup olmadığını merak ettiğim bir şeyle karşılaşıyorum. Aşağıdaki ifadeyi Verilen:if-let ifadesi isteğe bağlı açılmıyor

if let tabBarController = topViewController as? UITabBarController { 
     for subcontroller in tabBarController.viewControllers! { 
      println(subcontroller.view) 
      if let subcontrollerView = subcontroller.view { 
       println(subcontrollerView) 
       println(subcontrollerView!) 
       if subcontrollerView!.window != nil && subcontroller.isViewLoaded() { 
        topViewController = subcontroller as? UIViewController 
        break; 
       } 
      } 
     } 
    } 

Şimdi sıra bildiğim kadarıyla eğer-let deyimi benim için koşullu paketini gerektiğini - ama bu burada sergilenen davranış değildir. İsteğe bağlı olarak yeniden açmam sürece subcontrollerView numaralı window özelliğine erişemiyorum. X-kod konsol aşağıdaki verir:

Optional(<UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>>) 
Optional(<UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>>) 
<UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>> 

Çizelgesi opsiyonel ve eğer-let sürekli aynıdır. Niye ya?

+0

Hiçbir şey İsteğe bağlı nil ise unwrapped olacaktır. – gnasher729

+0

sağ, ama konsol çıkışına bakın - – kellanburket

+1

bana bir hata gibi görünüyor, bu küçük bir projede izole edebilir misiniz? Eğer öyleyse, onu buraya gönderebilirdiniz ve kendimize bir göz atabiliriz. Eğer hala bir projenin Apple'a bir radar göndermek için harika olacağı bir sorun varsa görünüyor. – drewag

cevap

6

Sorununuz: AnyObject. (Şüphe, senin sorunun hep AnyObject değil, mümkün olduğunca kaçınılmalıdır kötü bir türüdür kötüsü AnyObject? olduğunu..)

sorun tabBarController.viewControllers döner [AnyObject]? ve isteğe bağlı promosyon muhtemelen neden olmasıdır yanlara gitmek için şeyler. Bir AnyObject?'un bir AnyObject?? numarasına yükseltilmesi ve daha sonra karışık olması. Bu biraz derleyici bir böcek, aynı zamanda sadece AnyObject ile gelen delilik. Yani cevap, olabildiğince çabuk kurtulmak. Bunun yerine

:

if let viewControllers = tabBarController.viewControllers as? [UIViewController] { 
    for subcontroller in viewControllers { 

Yani tam kod şudur:

for subcontroller in tabBarController.viewControllers! { 

Bunu istiyorsun

if let tabBarController = topViewController as? UITabBarController { 
    if let viewControllers = tabBarController.viewControllers as? [UIViewController] { 
     for subcontroller in viewControllers { 
      if let subcontrollerView = subcontroller.view { 
       if subcontrollerView.window != nil && subcontroller.isViewLoaded() { 
        topViewController = subcontroller 
        break; 
       } } } } } 

Ama biz daha iyisini yapabiliriz. İlk olarak, isteğe bağlı zincirleme-izin verirse birden yönetmek için daha iyi bir yolu çoğu zaman olduğunu ve iyi çalışmadığı zaman, biz bu almak için Swift 1.2 'yeni çok if-let sözdizimi kullanabilirsiniz:

if let tabBarController = topViewController as? UITabBarController, 
    viewControllers = tabBarController.viewControllers as? [UIViewController] { 
     for subcontroller in viewControllers { 
      if subcontroller.view?.window != nil && subcontroller.isViewLoaded() { 
       topViewController = subcontroller 
       break; 
      } } } 
+1

Mükemmel bir cevap. @Rob - Apple neden abBarController.viewControllers dönüş türü için AnyObject kullanıyor. Neden sadece bir [UIViewController] dizisi döndürmek değil - sanırım viewControllers UIViewController alt sınıfları olacak? ... hala bu çirkin bir çözüm gibi görünüyor – Woodstock

+1

Çünkü hala Swift arayüzleri geçiş yapıyoruz. ObjC arabirimi, hiçbir tür bilgi sağlamayan bir "NSArray" döndürür. Apple'ın açıkça kullandığı otomatik dönüştürme senaryosu Swift'de '[AnyObject]?' A çeviriyor. Başka bir şey yapabilmek için Apple geliştiricilerinin API'yi el ile değiştirmesi gerekiyor. Her sürümde bu adımı atıyorlar, ancak henüz tamir edilmemiş birçok parça var. –

+0

gerçekten ... ViewController alt sınıf türleri bir tabBarController farklı olması muhtemel olduğundan gerçekten bir çözüm yok tahmin edin. – Woodstock