2015-12-15 3 views
3

Я был несколько дней назад из Objective-C, чтобы написать язык Swift, в проекте я столкнулся с проблемой. Эта проблема заключается в использовании функции responsesToSelector ("testEnum:"), чтобы проверить, следует ли реализовать функцию testEnum: , если параметр имеет значение, он вернет false, я попробовал другие типы, он вернет true, не знаю, в чем причина, см. следующий код, чтобы помочь мне решить его, большое спасибо!Почему delegate.respondsToSelector (Selector ("testEnum:")), этот код вернет false на языке быстрого доступа?

enum TestEnum { 
     case A 
     case B 
     case C 
    } 

    protocol TestAProtocol: NSObjectProtocol { 
     func testEnum(testEnum: TestEnum); 
     func testInt(testInt: Int); 
    } 

    class TestA: NSObject { 
     var delegate: TestAProtocol?; 

     func executeDelegateCallBack() { 
      if (delegate != nil && delegate!.respondsToSelector(Selector("testEnum:"))) { // delegate!.respondsToSelector(Selector("testEnum:")) return false ? 
       delegate?.testEnum(TestEnum.A); 
      } 

      if (delegate != nil && delegate!.respondsToSelector(Selector("testInt:"))) { // delegate!.respondsToSelector(Selector("testInt:")) return true ? 
       delegate?.testInt(0); 
      } 
     } 
    } 

    class TestB: NSObject, TestAProtocol { 
     func initTestB() { 
      let testA: TestA = TestA(); 
      testA.delegate = self; 
      testA.executeDelegateCallBack(); 
     } 

     // mark TestAProtocol 
     func testInt(testInt: Int) { 

     } 

     func testEnum(testEnum: TestEnum) { 

     } 
    } 
+2

Его не ответ на ваш вопрос, но ваш || должен быть && - Вы хотите, чтобы делегат был не ноль и отвечал на селектор – Paulw11

+0

Ну, я пишу тестовый пример, не слишком много внимания, спасибо, я его изменяю! –

ответ

6

respondsToSelector() использует среду выполнения Objective-C и работает только с методами, которые Objective-C совместимы. Swift enums может быть только , представленный в Objective-C, если они отмечены @objc и что требует, чтобы они имели целое исходное значение.

Так с

@objc enum TestEnum : Int { 
    case A 
    case B 
    case C 
} 

ваш respondsToSelector(Selector("testEnum:") вернется true.

Однако обратите внимание, что тестирование на наличие методы составляет лишь смысла с дополнительными методами протокола, и они доступны только для @objc протоколов, например:

@objc enum TestEnum : Int { 
    case A 
    case B 
    case C 
} 

@objc protocol TestAProtocol: NSObjectProtocol { 
    optional func testEnum(testEnum: TestEnum) 
    func testInt(testInt: Int) 
} 

И тогда много проще использовать опциональные цепочки вместо respondsToSelector:

func executeDelegateCallBack() { 
    delegate?.testEnum?(.A) 

    // ... 
} 

или более detaile d:

func executeDelegateCallBack() { 
    if let testEnum = delegate?.testEnum { 
     testEnum(.A) 
    } else { 
     print("delegate is `nil` or does not respond to `testEnum`") 
    } 

    // ... 
} 
+0

Я собирался опубликовать то же самое ... Одна небольшая коррекция: TestAProtocol не обязательно совместим с ObjC (по крайней мере, в Swift 2.0). –

+0

@ArthurGevorkyan: Это необходимо для 'необязательных' методов (по крайней мере, в моем Swift 2.1). –

+0

Теперь я вижу. С точки зрения опциональности вы правы. Я имел в виду, что не требуется, чтобы responseSoSelector: работать. –