Swift 5: Как протестировать AnyObject? переменная для типа значения? - PullRequest
0 голосов
/ 01 мая 2020

В настоящее время я портирую приложение iOS с Objective- C на Swift. Делая это, я просто наткнулся на проблему, с которой я борюсь.

У меня есть переменная («значение»), которая может ставить на AnyObject ?, особенно это может быть тип String, Array, Dictionary и Set. Теперь в моем предыдущем коде я тестировал свою переменную «value» для типа ее значения, чтобы продолжить работу с ним:

id value = [myDatahandler getValue];

if (([value isKindOfClass:[NSSet class]] || [value isKindOfClass:[NSArray class]]) && [value count] > 0) {
        // do something
}

Попытка сделать то же самое в Swift, похоже, не работает ...

var value: AnyObject? = myDatahandler.getValue()

if (value is Set || value is Array) && value!.count > 0 {
        // Error:
        // Generic parameter 'Element' could not be inferred in cast to 'Array'
        // Generic parameter 'Element' could not be inferred in cast to 'Set'
}

После нескольких часов поиска правильного способа сделать это, но не найдя ничего полезного, я надеюсь, что сообщество может прийти мне на помощь здесь ...

Любые предложения, как это может работать?

Ответы [ 3 ]

1 голос
/ 01 мая 2020

Я чувствую, что вы можете использовать охрану для этого .. Надеюсь, что следующий фрагмент кода работает.

guard let value =  myDatahandler.getValue() as? [Element] , value.count > 0 else {
    return
}

print(value)
0 голосов
/ 01 мая 2020

Проблема в том, что Set и Array являются общими c типами. Вы должны предоставить тип элемента.

Например, если вы ожидаете, что они содержат Strings:

if (value is Set<String> || value is Array<String>) && value!.count > 0 {

}

Если вам просто нужно, чтобы это был массив или набор (и вы не не заботится о типе элемента), вы можете использовать Any в качестве типа элемента:

if (value is Set<Any> || value is Array<Any>) && value!.count > 0 {

}
0 голосов
/ 01 мая 2020

Используйте Any вместо AnyObject, поскольку со страницы HackingWithSwift

AnyObject ссылается на любой экземпляр класса и эквивалентен id в Objective- C. Это полезно, когда вы специально хотите работать с ссылочным типом, потому что он не позволяет использовать какие-либо структуры или перечисления Swift. AnyObject также используется, когда вы хотите ограничить протокол, чтобы его можно было использовать только с классами.

Любой относится к любому экземпляру класса, структуры или перечисления - буквально к чему-либо вообще. Вы увидите это в Swift там, где типы неизвестны или смешаны способами, которые могут быть содержательно распределены по категориям:

Затем вы можете использовать защитный элемент для развертывания необязательного значения

guard let value =  myDatahandler.getValue() as? [YourClass], !value.isEmpty {
   return
}
...