#swift
#swift
Вопрос:
Согласно iBook «Использование Swift с Cocoa и Objective-C» (около Loc 9) относительно id
совместимости:
Вы также можете вызвать любой метод Objective-C и получить доступ к любому свойству без приведения к более конкретному типу класса.
Пример, приведенный в книге (показан ниже), не компилируется, что, по-видимому, противоречит приведенному выше утверждению. Согласно книге, последняя строка ниже не должна выполняться, потому length
что свойство не существует для NSDate
объекта.
var myObject: AnyObject = UITableViewCell()
myObject = NSDate()
let myLength = myObject.length?
Вместо этого не удается выполнить компиляцию с ошибкой «Не удалось найти перегрузку для «длины», которая принимает предоставленные аргументы» в последней строке.
Это ошибка, опечатка или утверждение о вызове любого метода Objective-C неверно?
Ответ №1:
ошибка компилятора говорит length
, что это функция, и вы вызываете ее с неверными аргументами
вы можете сделать myObject.length?()
, который возвращает nil
также myObject.count?
выдаст вам nil
ошибку компиляции
xcrun swift
Welcome to Swift! Type :help for assistance.
1> import Cocoa
2> var obj : AnyObject = NSDate()
obj: __NSDate = 2014-06-25 13:02:43 NZST
3> obj.length?()
$R5: Int? = nil
4> obj.count?
$R6: Int? = nil
5> obj = NSArray()
6> obj.length?()
$R8: Int? = nil
7> obj.count?
$R9: Int? = 0
8>
Я думаю, что компилятор выполнял поиск по всем вызываемым методам и свойствам length
, он обнаружил, что какой-то класс предоставляет length()
, но класс не предоставляет length
, отсюда и сообщение об ошибке. Точно так же, как при вызове [obj nonexistmethod]
в ObjC, компилятор выдаст сообщение об ошибке « nonexistmethod
не существует», даже если вы вызываете его для id
типа object
Это то, что произошло, если вы попытаетесь вызвать несуществующий метод в Swift
14> obj.notexist?
<REPL>:14:1: error: 'AnyObject' does not have a member named 'notexist'
obj.notexist?
^ ~~~~~~~~
14> obj.notexist?()
<REPL>:14:1: error: 'AnyObject' does not have a member named 'notexist()'
obj.notexist?()
^ ~~~~~~~~
Комментарии:
1. Но есть много классов, которые принимают
length
, а неlength()
. Например,var data = NSMutableData(); let otherLength = data.length
будет компилироваться и работать.2. @JefferyRPrice возможно, это ошибка компилятора (или дефект языка). возможная причина, по которой
length
forNSData
не найден, потому что это не свойство ObjC, а обычный метод-[length]
, который имеет смысл переводитьlength()
вместоlength
3. Я могу в это поверить, но будет ли это квалифицироваться как ошибка, опечатка или подразумевать, что утверждение о вызове любого метода Objective-C неверно? Кроме того, в документации говорится, что объявление Obj-C для длины равно
@property(readonly) NSUInteger length
.