2014-07-06 12 views
15

w Objective-C, jeśli chciałem użyć określonej klasy, który jest obecny tylko w nowej wersji iOS, chciałbym zrobić coś takiego:Jak wykonać słabe linkowanie w Swift?

if([UIBlurEffect class]) { 
    // do something with UIBlurEffect 
} 
else { 
    // gracefully fallback to old behavior 
} 

jednak równoważne Swift:

if UIBlurEffect.self != nil { 
    let blur: UIBlurEffect = UIBlurEffect(...) 
    // ... 
else { 
    // ... 
} 

// also occurs with NSClassFromString("UIBlurEffect") 

nie ma tej samej funkcjonalności.

Jeśli jest dostępny w środowisku, w którym dostępne jest NSNewFeature, wszystko jest w porządku. Ale jeśli klasa nie jest zdefiniowana, pojawia się błąd łącza podczas uruchamiania aplikacji:

dyld: Symbol not found: _OBJC_CLASS_$_UIBlurEffect 

Więc jak mam zrobić słabe powiązanie w Swift?

Edytuj Dodano UIBlurEffect jako konkretny przykład.

+0

możliwe duplikat [ Co to jest preprocesor Swift równoważny z wersją sprawdzania wersji systemu iOS?] (Http://stackoverflow.com/questions/24166919/what-is-the-swift-preprocessor-equivalent-to-ios-version-check-compar ison) – user102008

+0

Domyślam się, że powinieneś użyć opcji opcjonalnej, coś jak na przykład featureAvailable = NSNewFeature? {} else {}. Ale jestem całkiem nowy na szybki – Andrea

+0

Niestety NSNewFeature.self – Andrea

Odpowiedz

5

Wydaje się jakbym zorientowali się, co można zrobić

  1. użyłem NSClassFromString() aby sprawdzić, czy klasa jest dostępny na urządzeniu, tj

    if NSClassFromString("UIBlurEffect") { 
        let blur = UIBlurEffect(...) 
        //... 
    } 
    else { 
        //... 
    } 
    
  2. Jest potrzebne, aby UIKit.framework (lub inne odpowiednie ramy) opcjonalne. Jeśli utworzysz aplikację opartą na Swift w XCode6-BetaX, wszystkie frameworki nie zostaną jawnie dodane do fazy budowania linku, więc musisz przejść do ustawień docelowych, dodać UIKit.framework jako połączoną strukturę (w 'Link Binary With Libraries' sekcja) i zmienić jego status na Optional. Ten krok wykonuje sztuczkę i udało mi się uruchomić bez problemu specyficzny dla wersji kod.

Aktualizacja: Nie musisz zrobić to już opcja, ponieważ Xcode 6 beta 6 (via @ user102008)

Update 2: Nie można wykonać niejawna jeśli rzeczywiście oświadczenie sprawdza wartość zerową (od Xcode 6 Beta 5). Trzeba stwierdzić, to tak:

if NSClassFromString("UIBlurEffect") != nil { 
     let blur = UIBlurEffect(...) 
     //... 
    } 
    else { 
     //... 
    } 

(poprzez @ Daniel-galasko)

+0

ale cały punkt wyrażenia 'import' ma na celu wyeliminowanie konieczności ręcznego dodawania struktur. – user102008

+0

Myślę, że to może być tylko błąd implementacji. Lub funkcja. Aktualizacja – Ievgen

+0

: nie musisz już dodawać opcji, w Xcode 6 beta 6 – user102008

2

Wystarczy dodać swoje trzy grosze odkąd skończyło się to do mojego bezpośredniego konsternacji na dystrybucję aplikacji do naszych testerów. Występuje błąd w kompilatorze Swift (Xcode < = 6.1.1), w którym podczas budowania w trybie Release kompilator faktycznie nie zwraca zero podczas wywoływania NSClassFromString.

Aby sprawdzić, po prostu zmień konfigurację na Release i zobacz, jak się rozbija.

Skończyło się na tym, że musiałem jawnie sprawdzić wersję dla systemu iOS lub wykonać proste wywołanie ResponsesToSelector w innym miejscu.

Więc gdzie jest mój kod wygląda tak:

if NSClassFromString("UIVisualEffectView") != nil { 
     //use the blur safely 
    } else { 
     //abandon blur! try something safer 
    } 

skończyło się na konieczności używania zamiast tego

switch UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch) { 
     case .OrderedSame, .OrderedDescending: 
      //go wild with blur 
     case .OrderedAscending: 
      //blur shall not pass here! 
     } 

To pytanie zadawane przy tej samej kwestii - UIAlertView is crashing app on iOS 7

+0

Interesujące - Czy to jeszcze się dzieje w wersji 6.3 beta? – Bill

+0

@Bill potwierdzi później, czy tak jest, mam nadzieję, że nie, ponieważ wspomnieli, że naprawili kilka problemów z optymalizacją wydania –