Мы рады поделиться еще одним релизом Swiftify, который сделает вашу жизнь немного проще. На этот раз мы рассмотрим различия между тем, как Objective-C и Swift обрабатывают типы.
Введите приведение для объявлений цикла
Objective-C накладывает очень мало ограничений на приведение типов. При попытке выполнить операции над объектами в NSArray вы можете сделать что-то вроде этого:
- (void)loopOverStrings:(nonnull NSArray *)stringArray { for (NSString *string in stringArray) { [self doWorkOnString:string]; } } - (void)doWorkOnString:(NSString *)string { // ... }
В этом коде нигде не говорится, что stringArray
на самом деле является массивом строк. Но Objective-C по-прежнему позволит вам преобразовывать объекты в stringArray
в NSString.
Swift не допускает такого рода неявное преобразование. Попытка привести объекты в stringArray
к типу String вернет необязательное значение, если это не удастся. Наш последний релиз обрабатывает приведение типов следующим образом:
func loopOverStrings(_ stringArray: [Any]) { for string: String in stringArray as? [String] ?? [String]() { doWork(on: string) } } func doWork(on string: String?) { }
Обратите внимание, что поскольку Objective-C stringArray
не указывает тип своих объектов, версия Swift — [Any]
. В объявлении цикла for
мы приводим массив к [String]
.
Вы можете поиграть с этим примером здесь:
Неявное приведение к логическому значению
Что общего между 0
, NO
и nil
в Objective-C?
Все они эквивалентны логическому значению false.
Это немного упрощение, но оно работает для следующей проблемы:
NSInteger var1 = -512; NSInteger var2 = 512; if (var1 + var2) { NSLog(@"Sum is not zero"); }
Тело оператора if не будет выполнено, поскольку var1 + var2 == 0
. 0 в Objective-C эквивалентен false, поэтому тело не выполняется. Если бы значение было отрицательным или положительным, оно равнялось бы true.
Мы исправляем эту причуду в последней версии:
var var1: Int = -512 var var2: Int = 512 if var1 + var2 != 0 { print("Sum is not zero") }
Это доступно для вас, чтобы попробовать на нашем сайте.
В том же духе мы можем проверить, является ли объект нулевым в Objective-C, следующим образом:
- (NSString *)resultMessageForData:(NSData *)data { return data ? @"Operation succeeded!" : @"Operation failed."; }
Если data
не равно нулю, метод вернет «Операция выполнена успешно!». Если он равен нулю, вместо этого будет возвращено «Операция не удалась».
В преобразовании Swift нам нужно напрямую сравнить data
с nil, потому что Swift не сделает этого за нас.
func resultMessage(for data: Data?) -> String? { return data != nil ? "Operation succeeded!" : "Operation failed." }
Попробуйте здесь:
Неявное преобразование нуля в логическое значение
Swiftify — конвертер Objective-C в Swiftswiftify.me
Необязательные параметры в интерполированных строках
Не знаю, как вы, но я столкнулся с изрядной долей ошибок, вызванных интерполяцией необязательных значений. В Swift вы можете легко комбинировать одну строку с другим объектом:
func logDate(date: Date?) { print("The date is \(date)") }
Вы можете ожидать такой вывод:
The date is 2018-04-16 11:40:36 +0000
Но Swift не делает никаких предположений о типе объектов: вы передаете ему необязательное значение, и он печатает его как таковое.
The date is Optional(2018-04-16 11:40:36 +0000)
Когда наш преобразователь увидит такой код:
- (NSString *)greetingForName:(NSString *)name { return [NSString stringWithFormat: @"Hello there, %@.", name]; }
Это разумно развернет необязательный для вас.
func greeting(forName name: String?) -> String? { return "Hello there, \(name ?? "")." }
Попробуйте:
Что бы вы хотели видеть от Swiftify?
Видели ли вы какие-либо дела, которые хотели бы автоматизировать с помощью Swiftify? Дайте нам знать в комментариях ниже!