Задать вопрос
Ответы пользователя по тегу iOS
  • Почему происходит ошибка разворачивания инициализированного опционала,?

    А зачем вам здесь вообще Bool? понадобился?
    Если флаг успеха, то лучше var per2 = false.
    Ещё, у вас есть блок try-catch, но в нём ни одного try.
    Ещё, вы выводите не-развёрнутый Optional, о чём, к счастью, предупредит компилятор.
    Кроме того, у вас может произойти отказ в разных местах, так что стоит подумать над использованием ошибок / "исключений" Swift:

    func aaa() throws {
                let fetchResult = try PersistenceService.contex.fetch(fetchRequest)
    
                for item in fetchResult {
                    let per = item.password
                    guard let pass = per else {
                        throw AaaErrors.passwordNotCreated
                    }
                    print("пароль \(pass!)")
                }
        }
    Ответ написан
    Комментировать
  • Что означают A.Type и A.self, где A - некий класс, в языке Swift?

    Для любого типа T, T.Type - это метатип (metatype), то есть тип, объекты которого предоставляют описание типа T. Статические функции и init-функции T становятся функциями-членами T.Type. Пример:

    struct Duck {
        static func kind() -> String { return "Bird" }
        init() { }
        func talk() { print("Quack") }
    }
    
    let meta: Duck.Type = Duck.self
    meta.kind()  //=> Bird
    let obj: Duck = meta.init()
    obj.talk()  //=> Quack


    Существует 2 класса метатипов, но на практике встречаются existential metatypes, то есть их объекты могут описывать как данный тип T, так и любой наследник (subtype) типа T. Другими словами, множество объектов типа T.Type - это U.self для всех типов U: T. Пример:

    class Animal { class var name: String { return "Animal" } }
    class Cat: Animal { override class var name: String { return "Cat" } }
    class Dog: Animal { override class var name: String { return "Dog" } }
    
    var meta: Animal.Type
    meta = Cat.self
    meta.name  //=> Cat
    meta = Dog.self
    meta.name  //=> Dog


    Или, например, можно представить себе такую функцию генерации животных:

    class Animal { ... }
    
    func createAnimal(_ type: Animal.Type) -> Animal {
        if type == Cat.self {
            return Cat(...)
        } else if type == Dog.self {
            return Dog(...)
        } else {
            fatalError()
        }
    }


    На практике, такая функциональность метатипов используется редко. Как правило, они служат для явной специализации шаблонных функций. Например:

    func unsafeCast<T, U>(_: T, to: U.Type) -> U

    Здесь единственный способ указать тип U при вызове - это передать "фиктивный" параметр тип U.Type, так как аргументов типа U функция не принимает. Вернее, это лучший и принятый в Swift способ. Можно было бы выкрутиться вот так:

    func unsafeCast<T, U>(_: T, sameAs: U) -> U

    Но, понятно, что для этого нужно иметь под рукой объект типа U, и это не идеальный вариант. Жаль, что нельзя писать просто unsafeCast<U>(t) при вызове.

    При использовании метатипа U.Type таким образом, его значение, как правило, игнорируется. То есть даже если вы передадите туда метатип наследника типа U, то функция всё равно будет работать с U.

    P.S. Есть ещё много недокументированных фич метатипов в Swift, но там всё не очень логично и продуманно (даже разработчики из Core team не всё там понимают), так что на практике лучше ограничиться применением для явной специализации функций, как показано выше.
    Ответ написан
    1 комментарий
  • Как изменить глобальную переменную контроллера?

    Возможно, UserService.getUsers - это асинхронная операция. В этом случае код в замыкании выполнится позже, чем код после вызова getUsers.
    Ответ написан
    1 комментарий
  • Как конвертировать MapKit MKCoordinateSpan в Float|Int для Google Maps?

    Если нужно просто преобразовать тип числа из Double во Float, то в Swift это выполняется с помощью конструктора:
    let coordinateSpan: MKCoordinateSpan = ...
    let latitudeFloat = Float(coordinateSpan.latitudeDelta)
    let longitudeFloat = Float(coordinateSpan.longitudeDelta)
    Ответ написан