Pull to refresh

Comments 29

Многое из описанного актуально для других платформ, а не только для iOS и Swift.
Обновление UI не из UI потока, по моему глобальное правило иначе как ОС гарантирует адекватное состояние UI?
В последнем примере кода, onSuccess, вызванная из главного треда(а такая необходимость иногда возникает) вызовет дедлок (если не ошибаюсь). Надо бы проверять перед вызовом updateUI() в каком треде находишься. И, если в главном, то просто updateUI() без dispatch_sync(...)
Спасибо за подсказку!!!
Да, на всякий случай обертку dispatch нужно перенести непосредственно в код колбека.
>в результате мы получаем два объекта в памяти, строго ссылающихся друг на друга — и они никогда не вычистятся
т.е. GC не обрабатывает циклические ссылки?
С первого марта по-моему никаких GC только ARC для Apple Store
GC был доступен только для OS X. С первого марта всего-лишь запрещено использование GC. Можно заливать приложения как с ARC так и с ручным подсчетом указателей.
Если внутри замыкания НЕ используется вызов self, то такого подвоха НЕ возникает.

На самом деле отсутствие self не гарантирует отсутствия циклических ссылок.
Например, если вместо self передать другую переменную ссылающуюся на self, то это породит циклические ссылки:
var me: ViewController = self
whatToDo = { println(me.theString) }

Все-таки нужно логически понимать, что происходит в коде.
Да, действительно, я хреново сформулировал, на самом деле закрепляются в строгих ссылках вообще все закепчеренные блоком обьекты классов.
Спасибо за замечание!!!

Простите, вы читаете со скоростью 500 страниц в час? Или вы про главу Swift Tour?
Воистину птичий язык. Какая зараза кричала, что это проще и информативнее ObjC?
На самом деле вход в Swift на много проще чем в obj-c
Я например в Swift вошол с полпинка, в то время как в obj-c просто не мог себя заставить, просто синтаксис ужасный для меня,… (тут уже эмоции от синтаксиса переполняют)
Все дело в том что синтаксис у него интуитивно понятен и похож на распространенные языки. Если пришли в ios например с Java, Php, JS, C# то проще всего заходить через Swift, гараздо меньше нервов потратишь, в то время как при переходе на obj-c дергается а потом и вовсе ломается глаз от того что все как то через задний проход.
Но чтение вводной документации никто не отменял ни в каком языке
Лично меня в свифте уже один только восклицательный знак убивает. Как можно при описании методов использовать такой символ? Вообще, язык выглядит как движение в сторону JavaScripta, что лично я считаю неприемлемым.
Никто не говорит что он совершенен, я говорил про порог вхождения.
Что именно неприемлемо в схожести с JS? Я считаю это большим плюсом для переходящих программистов.
Наверное, я просто олдфаг, не обращайте внимания :)
Стремление создателей сделать синтаксис максимально кратким породило кучу вариаций синтаксического сахара, от которых мозг взрывается.
Где пример с whatToDo, там можно использовать слабую связку аля {[weak self] () in println("\(self!.myvar)")}

По поводу передачи по ссылке страктов и массивов, можно их передавать в режиме ссылки, для этого достаточно указать inout, например так:
func myFunc(inout var persons: [PersonStruct]) {...}

Также если надо вернуть из функции ссылку то можно использовать UnsafeMutablePointer
inout — работает, спасибо!!!
Точнее даже вот так:
func addJoeyTo(inout persons:[Person]) { // не inout var, а просто var
    persons.append(Person(name: "Joey", age: 25))
}
...
addJoeyTo( &programmers ) // нужно использовать &
Ну и weak и unowned работает только для class типов
Если планируется передача по ссылке чего-то, то лучше оформлять это дело в виде класса.
Третий пункт про синглетоны не верен. class var уже давно работает, кажется с релиза XCode 6.1. Сейчас самый логичный способ создать синглетон на свифте вот такой:

private let _sharedInstance = Singleton()

class Singleton {
    class var sharedInstance : Singleton {
        return _sharedInstance
    }
}
Спасибо за комментарий! Но в вашем примере вычисляемый class var, а не хранимый. Именно поэтому приходится выносить инициализацию во внешний scope. ;) Этот подход тоже используется — правда, он не lazily loaded.
Его легко можно сделать lazily loaded — все глобальные переменные в свифте lazy loaded, можно дополнительно сделать конструктор вот такого вида

private let _sharedInstance: Singleton  = {
    let singleton = Singleton()
    singleton.property = ...
    return singleton
}()

class Singleton {
    class var sharedInstance : Singleton {
        return _sharedInstance
    }
}
Ещё могу добавить одну ловушку: блоки не передаются аргументом в функцию, т.к хранятся только в стеке.
В Obj-C можно объявить специальное Property типа блока, пометить его (atomic, copy), и только(!) тогда эти property можно передать аргументом.
К сожалению не в курсе какая замена (atomic, copy) для этого существует в Swift, может кто подскажет?
Я попробовал, вроде все блоки передаются спокойно!)
class Test {
    typealias T = (()->Void)
    func test(foo:T) {}
    let foo1:T = { }
    init () {
        let foo2:T = {}
        test(foo1)
        test(foo2)
    }
}

Ошибок нет
Приношу свои извинения, я действительно неправильно высказался насчёт блоков. Блоки можно использовать, но они прекращаются в ничто после выхода из функции, где объявлены. Таким образом их нельзя вернуть в качестве результата и нельзя использовать в коллекциях. Но это всё исправляется, как только вы начинаете использовать свойства (atomic, copy). Например:
Это рабочий код:
init() {
  let foo2:T = { print("Hello") }
  test(foo:T) { foo() }
}

А этот код должен упасть (насколько я незнаком со Swift):
give() {
  return { print("Hello") }
}
init() {
  let foo = give()
  foo()  
}

Есть хорошая статья на эту тему Objective-c блоки и c++ лямбды
это не совсем так, любая запись блока в strong переменную порождает копирование в кучу
Array, Dictionary и Struct по умолчанию немутабельные типы, никогда не передающиеся по ссылке

по-моему, стоит упомянуть и про String в данном контексте
Sign up to leave a comment.

Articles