Вызов функции Swift из Objective-C с параметром - PullRequest
0 голосов
/ 31 мая 2018

Я хочу интегрировать класс Swift в класс UIViewController.Я думаю, что я сделал все настройки правильно.У меня есть класс rURLTask: NSObject с функцией:

@objc public func primer() {
    print("primer")
}

в моем файле .swift, и я могу вызвать его из моего класса Objective-C с помощью:

[URLTask primer];

, и он печатаетмило.Другая функция:

@objc public func ladeURL(url: URL?) {
    print("loadURL")
}

, но эту функцию я не могу вызвать из Objective-C.Я пытаюсь написать:

NSURL* testURL = [NSURL URLWithString:@"http://www.google.com"];    
[URLTask ladeURL:testURL];

Я получаю ошибку:

Нет видимого @interface для 'rURLTask' объявляет селектор 'ladeURL:'

Я думаю, что есть очень основная ошибка.Использование Objective-C в Swift 3 в другом проекте работало хорошо.

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Когда вы импортируете класс в OC, имя метода, написанного на swift, переводится конкатенированным с withParameterType , так как простой метод

@objc public func primer() {
  print("primer")
}

не имеет параметров, которые могут бытьназывается так

[URLTask primer];

но это

@objc public func ladeURL(url: URL?) {
   print("loadURL")
}

переводится как

[URLTask ladeURLWithUrl:<#NSURL#>];
0 голосов
/ 31 мая 2018

Причина, по которой вы не можете вызвать

@objc public func ladeURL(url: URL?) {
    print("loadURL")
}

, сказав

[URLTask ladeURL:testURL];

, заключается в том, что ladeURL: - это , а не название этого метода, поскольку Objective-C Это то, что имеет в виду компилятор, когда он говорит, что «Нет видимого @interface для 'rURLTask' объявляет селектор ladeURL:».

Его имя для Objective-C это ladeURLWithUrl:.Это потому, что вы выставили имя параметра url: как внешнюю метку.


Если для вас было важно иметь возможность сказать

[URLTask ladeURL:testURL];

в Objective-C, вы могли бы объявить ladeURL так:

@objc public func ladeURL(_ url: URL?) {
    print("loadURL")
}

Видите подчеркивание?Это скрывает внешнюю метку параметра.


Другое решение, позволяющее сохранить внешнюю метку url:, - объявить имя Objective-C как часть атрибута objc:

@objc(ladeURL:) public func ladeURL(url: URL?) {
    print("loadURL")
}

Это говорит компилятору: «Я знаю, что вы хотели бы перевести имя этого метода в Objective-C как ladeURLwithUrl:, но не переводите еговместо ladeURL:. "

...