Не удается преобразовать код view.tag ObjC в Swift

Я переношу некоторый код в Swift и наткнулся на эту строку, которая по какой-то причине работает с ObjC, но не со Swift.

Объект:

if (view.tag == 'C'+'L'+'O') {

А теперь то, что я написал в Swift, что не работает:

if view.tag == "C" + "L" + "O" {

Там написано Ambiguous reference to operator function '=='

Почему это? Как я могу это исправить?


person Nachot93    schedule 27.11.2019    source источник
comment
Мой общий совет по этому поводу — просто притвориться, что тегов не существует. Это была ошибка дизайна, IMO, так как существует очень много разных, гораздо лучших способов определения дочерних представлений.   -  person Alexander    schedule 27.11.2019
comment
Тогда я постараюсь подойти к этому иначе. Благодарю вас!   -  person Nachot93    schedule 27.11.2019


Ответы (2)


'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 дает несколько хороших альтернатив в своем ответе.

person vacawama    schedule 27.11.2019
comment
Понятно. Спасибо за ваш ответ! - person Nachot93; 27.11.2019

В C и ObjC символы (обозначаемые одинарной кавычкой ' вместо двойных кавычек " для строк) на самом деле являются целыми числами, поэтому вы можете сложить их вместе и назначить их tag, который является целым числом.

В Swift есть символьный тип, но это не int, и в этом случае вы добавляете три строки, в результате чего получается строка "CLO", которую нельзя присвоить свойству tag, поскольку это свойство является int.

Лично я против использования тегов представления, я предпочитаю создание подкласса и создание новой переменной для хранения соответствующей информации.

Однако, если вы хотите продолжать использовать теги, вы можете использовать хэш-значение строки, поэтому if view.tag == "CLO".hashValue. Это не совсем эквивалентно, так как "CLO".hashValue будет отличаться от "COL".hashValue, чего не будет в ObjC. ПРИМЕЧАНИЕ. Как упомянул @Alexander, хэш-значение будет разным при каждом запуске приложения. Если вы сохраняете данные между запусками, не используйте hashValue

Лучшей альтернативой было бы создать перечисление с поддержкой int и добавить их необработанные значения.

Еще лучшей альтернативой было бы создать набор опций, создать подкласс или UIView или что-то еще, что вы используете, и добавить свойство для их хранения там. Затем вы можете проверить, есть ли в представлении все необходимые вам значения.

person EmilioPelaez    schedule 27.11.2019