2016-11-16 2 views
0

Любая идея, почему я мой Swift 3 IOS приложение, этоТребование @objc для Swift 3?

@objc(mapView:rendererForOverlay:) func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { 

триггерами, , но если я заменю выше заявление с этим

func mapView(mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { 

не срабатывает.

+0

Нет, я имел в виду, что если я заменю верхний оператор ниже, он перестанет работать. – Kashif

+0

Отредактировано для пояснения – Kashif

ответ

2

Правильный ответ мата Я хочу объяснить причину подчеркивания.

Зачем нужен символ подчеркивания?

Короткий ответ: Потому что это объявление метода:

optional func mapView(_ mapView: MKMapView, 
     rendererFor overlay: MKOverlay) -> MKOverlayRenderer 

https://developer.apple.com/reference/mapkit/mkmapviewdelegate/1452203-mapview

Длинный ответ:

TL; др: Вам это нужно, чтобы удалить ведущее имя параметра для первый параметр в Swift 3.0.

Чтобы понять, что вы должны знать всю историю:

Objective-C имеет родственный именованные аргументы: Вся декларация способа включает в себя части перед декларацией параметра является частью идентификатора метода. Имея метод ...:

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView 
     rendererForOverlay:(id<MKOverlay>)overlay; 

... это означает, что идентификатор метода (селектора) является mapView:renderForOverlay:. Эта система была простой и долгое время использовалась. Он был мощным, потому что он делает ненужным перегрузку метода.

В соответствии с принципом проектирования Свифта, чтобы работать и простые вещи, которые сложны, что невозможно сказать, является ли они работают, они сделали несколько хитрых хаков:

Swift имеет родственный механизм перевода с Objective-C селекторов для функции Swift и идентификаторов параметров. Они нашли отличное решение в Swift 1.2 (?), Что делает вещи намного проще. Позже они признали, что большое и простое решение сбивает с толку, и они предложили новое решение в Swift 2.0, которое намного больше и проще.Позже они признали, что большее и простое решение сбивает с толку, и они предложили новое решение в Swift 3.0, которое намного больше по дальности.

В то время как в Swift < 3.0 первое (внешнее) имя параметра по умолчанию не имеет значения (поскольку первая часть селектора становится именем функции) это правило больше не применяется, и вы должны указать это. Подчеркивание просто говорит, что внешнего имени нет. Таким образом, ваше имя метода правильно переводится в селектор Objective-C.

Он принимает имя функции mapView не добавляет внешнего имени из-за _, поэтому это mapView:. Затем добавляется следующее внешнее имя параметра renderFor, что приводит к mapView:renderFor, затем имя параметра overlay, запишите его в Overlay, что приводит к mapView:renderForOverlay: - правильному селектору.

Довольно просто, довольно просто. Еще одна особенность, которая делает вещи в Swift великолепными и легкими. Намного проще, чем в Objective-C

1

Одна очевидная проблема заключается в том, что в Swift 3, это не правильная подпись:

func mapView(mapView: MKMapView, 
    rendererFor overlay: MKOverlay) -> MKOverlayRenderer { 

correct signature является:

func mapView(_ mapView: MKMapView, 
    rendererFor overlay: MKOverlay) -> MKOverlayRenderer { 

Обратите внимание на разницу (далее "подчеркивание").

Другая возможная проблема возникает, если ваш код не находится внутри объявления класса или расширения, что явно объявляет соответствие MKMapViewDelegate. Swift 3 очень разборчив. (Вы не указали достаточно контекста, чтобы узнать, правильно ли вы получаете эту часть.)

Объявление @objc работает обо всех проблемах, явно перекрывая эту функцию до Objective-C. Но если вы сделаете это правильно по обоим пунктам, Swift сделает мосты для вас, а @objc не понадобится.

+0

Что означает _? – Kashif

+0

Это «подчеркивание», о котором я говорю. Это важно. Вставьте его, как я показал, и ваш код будет вызван. – matt

Смежные вопросы