Zaczynam uczyć się Swift i śledzę bardzo dobre wykłady wideo z Uniwersytetu Stanforda na YouTube. Oto link, jeśli jesteś zainteresowany lub pomaga (choć nie jest to konieczne do zrozumienia mojego problemu):
Tworzenie aplikacji dla systemu iOS 8 za pomocą Swift - 2. Więcej Xcode i Swift, MVC
Podczas wykładów dotarłem do punktu, w którym (o ile mogłem powiedzieć) mój kod był identyczny z kodem w filmie, ale w moim systemie wystąpił błąd kompilatora. Po wielu próbach i błędach udało mi się zredukować kod do dwóch przykładów, z których jeden generuje błąd, drugi lub który nie, ale nie mam pojęcia, co tak naprawdę powoduje błąd ani jak go rozwiązać.
Kod, który powoduje błąd to:
import UIKit
class BugViewController: UIViewController
{
func perform(operation: (Double) -> Double) {
}
func perform(operation: (Double, Double) -> Double) {
}
}
Powoduje to następujący błąd kompilatora:
Metoda „perform” z selektorem celu C „perform:” koliduje z poprzednią deklaracją z tym samym selektorem celu C
Po prostu usuwając podklasę UIViewController kod kompiluje:
import UIKit
class BugViewController
{
func perform(operation: (Double) -> Double) {
}
func perform(operation: (Double, Double) -> Double) {
}
}
Niektóre inne informacje, które mogą, ale nie muszą być istotne:
- Niedawno uaktualniłem do Yosemite.
- Kiedy zainstalowałem Xcode, skończyłem z wersją Beta (wersja 6.3 (6D543q)), ponieważ (jeśli dobrze pamiętam) była to wersja, którą musiałem uruchomić na mojej wersji OS X.
Mam nadzieję, że jest to błąd w kompilatorze, ponieważ w przeciwnym razie nie ma to dla mnie żadnego sensu. Każda pomoc otrzymana z wdzięcznością!
Odpowiedzi:
Cel C nie obsługuje przeciążania metod, musisz użyć innej nazwy metody. Kiedy odziedziczyłeś UIViewController, odziedziczyłeś NSObject i uczyniłeś klasę współdziałającą z Obj-C. Z drugiej strony Swift obsługuje przeciążenie, dlatego działa po usunięciu dziedziczenia.
źródło
UIFont
co dzień.Ja również biorę udział w kursie w Standford i utknąłem tutaj również przez długi czas, ale po kilku poszukiwaniach znalazłem coś stąd: informacje o wydaniu Xcode i wspomniałem o tym poniżej:
po prostu dodałem „private” przed metodą przesłonięcia w następujący sposób:
źródło
Jak już odpowiedziano, ObjC nie obsługuje przeciążania metod (dwie metody o tej samej nazwie), aw swift 2 pod Xcode 7 istnieją dwie opcje rozwiązania tego rodzaju problemów. Jedną z opcji jest zmiana nazwy metody za pomocą atrybutu:
@objc(newNameMethod:)
inną opcją rozwiązania tego problemu w Xcode 7+ jest zastosowanie
@nonobjc
atrybutu do dowolnej metody, indeksu dolnego lub inicjatoraźródło
IS problemem
UIViewController
jest@objc
klasa. Dziedzicząc poUIViewController
,BugViewController
jest również@objc
klasą.Oznacza to, że musi być zgodny z regułami selektorów Objective-C (nazwa metody). Metody
func perform(operation: (Double) -> Double)
ifunc perform(operation: (Double, Double) -> Double)
obie mają ten sam selektor@selector(perform:)
. To jest niedozwolone.Aby rozwiązać ten problem, użyj różnych nazw: jak
func perform1(operation: (Double) -> Double)
ifunc perform2(operation: (Double, Double) -> Double)
.Myślę, że najlepszym sposobem na poradzenie sobie z tym jest nadanie
perform()
metodom bardziej opisowych nazw. Co robią te metody? Jak zmieniają stan kontrolera widoku? Spójrz na inneUIViewController
metody, aby poczuć styl nazewnictwa metod, lub przeczytaj Nazwy metod powinny być wyraziste i unikalne w obrębie klasyźródło
Od https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html w sekcji „Informacje o wersji Xcode 6.3” -> „Szybkie zmiany językowe” znajdziesz
źródło
Wystąpił ten sam błąd, ponieważ mam dwie metody z tym samym podpisem Obj-C:
Nie chciałem oznaczać jednego z nich jako @nonobjc ze względu na możliwość nieprzewidzianych konsekwencji w czasie wykonywania. (Ktoś może mnie poprawić, jeśli nie ma takiej możliwości)
Rozwiązano go za pomocą funkcji zewnętrznej nazwy parametru Swift (nazwa zewnętrzna jest taka sama jak nazwa lokalna) do drugiej metody, która skutecznie zmienia sygnaturę metody Obj-c:
źródło