Не удается преобразовать код view.tag ObjC в Swift
Автор вопроса: Nachot93Ответов: 2
Я переношу некоторый код в Swift и наткнулся на эту строку, которая по какой-то причине работает с ObjC, но не со Swift.
Объект:
if (view.tag == 'C'+'L'+'O') {
А теперь то, что я написал в Swift, что не работает:
if view.tag == "C" + "L" + "O" {
Там написано Ambiguous reference to operator function '=='
Почему это? Как я могу это исправить?
Мой общий совет по этому поводу - просто притвориться, что тегов не существует. Это была ошибка дизайна, IMO, так как существует очень много разных, гораздо лучших способов определения дочерних представлений. Alexander 27.11.2019
Тогда я постараюсь подойти к этому иначе. Благодарю вас! Nachot93 27.11.2019
'C', 'L' и 'O' в языках на основе C - это char, которые представляют собой 8-битные целые числа со знаком (или без знака), поэтому их значения можно складывать и сравнивать с Int.
Вы пытались добавить "C", "L" и "O", которые равны String, поэтому результатом конкатенации строк является String"CLO". В Swift нельзя сравнивать String с Int. По общему признанию, это было бы лучшим сообщением об ошибке.
Эквивалентом в Swift будет:
if view.tag == UnicodeScalar("C").value + UnicodeScalar("L").value + UnicodeScalar("O").value {
Это действительно ужасно по ряду причин, включая тот факт, что порядок не имеет значения, поэтому "C" + "L" + "O" и "O" + "C" + "L" дают один и тот же результат. В Swift существуют лучшие альтернативы. @EmilioPelaez дает несколько хороших альтернатив в своем ответе.
Ответ 2 · рейтинг 3 · EmilioPelaez
В C и ObjC символы (обозначаемые одинарной кавычкой ' вместо двойных кавычек " для строк) на самом деле являются целыми числами, поэтому вы можете сложить их вместе и назначить их tag, который является целым числом.
В Swift есть символьный тип, но это не int, и в этом случае вы добавляете три строки, в результате чего получается строка "CLO", которую нельзя присвоить свойству tag, поскольку это свойство является int.
Лично я против использования тегов представления, я предпочитаю создание подкласса и создание новой переменной для хранения соответствующей информации.
Однако, если вы хотите продолжать использовать теги, вы можете использовать хэш-значение строки, поэтому if view.tag == "CLO".hashValue. Это не совсем эквивалентно, так как "CLO".hashValue будет отличаться от "COL".hashValue, чего не будет в ObjC. ПРИМЕЧАНИЕ. Как упомянул @Alexander, хэш-значение будет разным при каждом запуске приложения. Если вы сохраняете данные между запусками, не используйте hashValue
Лучшей альтернативой было бы создать перечисление с поддержкой int и добавить их необработанные значения.
Еще лучшей альтернативой было бы создать набор опций, создать подкласс или UIView или что-то еще, что вы используете, и добавить свойство для их хранения там. Затем вы можете проверить, есть ли в представлении все необходимые вам значения.