Обновление UIImageView после applicationWillEnterForeground

uiimageview
swift3

#1

Добрый день Друзья

  1. Есть проблема с обновлением UIImageView после возвращения пользователя в приложение

  2. UIImageView берет изображение с url который у пользователя в Clipboard

  3. Метод сохранения func getDataFromUrl(url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) { URLSession.shared.dataTask(with: url) { data, response, error in completion(data, response, error) }.resume() }

Прошу помочь опытных коллег. Я только купил курсы))))


#2

Опять куча восклицательных знаков. Кто же вас так учит? Неужели Иван? И self в теле замыкания без [unowned self].

Скорее всего проблема в принудительном извлечении значения из опционала с помощью восклицательного знака.


#3

Благодарю за наводку)) буду копать и стараться вообще стереть знак ! с клавиатуры))))


#4

И что, по вашему нужно везде лепить weak/unowned?


#5

Вот такая запись хороша с точки зрения лаконичности, но не очень хороша для поиска ошибок.
Пока вы учитесь, лучше писать так:

if error != nil {
    print (error)
    return
} 
guard let data = data else {
    return
}
guard let imageFromData = UIImage(data: data) else {
    return
}

Тогда в любом месте можно поставить точку останова и посмотреть, что происходит в отладчике. Это лучше, чем написать на форум и ждать, пока кто-то ответит.


#6

Лучше лепить, чем не лепить. Кодирование - это процесс итеративный. Сначала написал, потом вернулся, поправил, снова вернулся, снова поправил. Код в замыкании может постоянно меняться и усложняться. И очень легко забыть про [unowned self] на каком-то этапе, особенно, когда мысли заняты другим. А потом возникают утечки, которые трудно находить. Поэтому, на мой взгляд, лучше сразу писать [unowned self]. А еще лучше писать

obj.myClosure { [weak self] in
    guard let this = self else {return}
    this.myvar = "something"
}

Потому что в какой-то момент и self может оказаться недоступной. Но это уже для совсем параноиков.
Вы пишите как хотите, мне все равно.


#7

Утечки возникают только в результате цикла сильных ссылок (вы похоже не знаете что это, советую ознакомиться) вот когда он возникает тогда и нужно писать weak/unowned, в коде выше, цикла нет :wink: Если вы наугад лепите weak/unowned, стоит вам посочувствовать.


#8

Я знаю, что такое сильные ссылки, не надо строить из себя гуру. По-моему, я ясно написал, что в какой-то момент в очередной итерации рефакторинга может возникнуть такая ситуация, когда появится сильная ссылка. И тогда придется написать [unowned self]. Но в этот момент голова может быть занята другим, и можно упустить этот важный момент. Так лучше сразу приучиться писать [unowned self]. Я сам сторонник короткого кода, но не в этом случае. А в командной работе поставить [unowned self] вообще правило хорошего тона.

Вы, похоже, никогда не писали ничего сложнее учебных примеров и не работали в команде. Нахватались по верхам и строите из себя Великого Учителя.


#9

Ок, приведите пример цикла сильных ссылок с замыканием)

Я из себя ничего не строю, просто вы мелите откровенную чушь.


#10

Господа, программирования это креатив, давайте не ругаться. Я попробую оба варианта. Они оба рабочие. После дебага отпишусь, что сработало. Спасибо за Ваши знания!


#11

Господа, программирования это креатив, давайте не ругаться. Я попробую оба варианта. Они оба рабочие. После дебага отпишусь, что сработало. Спасибо за Ваши знания🤓


#12

В чем чушь? Что программирование это бесконечный цикл рефакторинга? Или что поставить для коллег [unowned self] это правильно?

Перед вами сдавать экзамен не собираюсь. Вы вообще кто?)))


#13

В том что, вы не понимаете о чём говорите (даже пример не можете привести) но твёрдо уверены что в замыкании нужно писать unowned, еще и другим советуете, это даже смешно :smile:

А если вы в команда так пишите и никто не знает зачем, пора вас всех уволить.


#14

Вы утверждаете, что такие ситуации отсутствуют в принципе, когда в замыкании возникает сильная ссылка? Поэтому писать [unowned self] не нужно никогда? Я утверждаю, что такие ситуации бывают, поэтому писать эти два слова нужно всегда на всякий случай (запомните - программирование это бесконечный рефакторинг), потому что находить ошибки утечек памяти очень трудно. Но учить вас не собираюсь, оставайтесь в своем неведении дальше.


#15

Где это я такое утверждаю?

В отличии от вас я знаю когда возникают такие ситуации и где нужно писать weak/unowned.

Это говорит о вашей некомпетентности, вчера свифт учить начали? Так подучите ещё, а потом уж спорьте :slight_smile:


#16

Все говорит о вашей некомпетентности. Ясно, что вы никогда не работали над проектами и только учебные примеры разбирали. А о сложностях реальной работы никогда не слышали.

Поэтому у вас все в вакууме: ну возникнет такая ситуация, напишу [unowned self], какие проблемы? А пока писать не буду. Я же ведь великий и всегда начеку. И коллега пускай повнимательнее будет, глаза же ему на что-то даны. Не увидит, сам виноват будет. Вот так вы рассуждаете.

Это рассуждения дилетанта, которого к программированию вообще подпускать нельзя. А вы тут ходите и строите из себя невесть что.

Это еще хорошо, что свифт язык безопасный. Мне страшно подумать, что бы вы с таким подходом наворотили на С/С++.


#17

Ну конечно, куда мне до вас и вашей команды, которая язык выучить не может и везде лепит unowned “на всякий случай” :slight_smile: Смех да и только.


#18

Ну так и быть, проведу ликбез. Специально для вас почти в три ночи родил пример. Вот у вас есть класс:

class Obj {
    private var _prop = "secret"
    
    lazy var getProp: () -> String = {
        var value = "some "
        return value
    }
}

Вот так вы его используете:

override func viewDidLoad() {
    super.viewDidLoad()
    let obj: Obj? = Obj()
    if let myValue = obj?.getProp {
        let result = myValue()
        print (result)
    }
}
```
И все у вас хорошо. Но через какое-то время, через недельку, исправляя другие баги или выполняя новые пожелания заказчика, вы вносите исправление:
```
class Obj {
    private var _prop = "secret"
    
    lazy var getProp: () -> String = {
        var value = "some "
        value += "\(self._prop) 123" // вот тут
        return value
    }
}
```
Вы можете поклясться себе, работодателю, заказчику и коллегам, что не забудете при этом написать [unowned self]? Если вы скажете "да", то программирование вам противопоказано.

В реальной жизни встречаются намного более запутанные случаи. Которые к тому же могут быть написаны не вами на 100%.

Поэтому мой вам совет (хотя давать вам какие-то советы бессмысленно, у вас случай клинический), всегда пишите [unowned self] сразу. Хотя бы для коллег. Потому что за ваши фокусы рано или поздно вас начнут бить, как Шуру Балаганова. Засранный вами код никому не понравится прибирать вечно.

Я себе представляю такую картину: тим-лидер забегает весь красный от тестировщиков и орет: "Опять где-то течет!!! Какой мудак опять напортачил?!!!" И все программеры сразу головы в вашу сторону поворачивают)))

#19

Утечки памяти - это самые противные ошибки. Как правило, их поиск сводится к тому, чтобы закомментировать разные участки кода и локализовать место утечки. Есть специальные инструменты, но и они далеко не всегда помогают быстро локализовать ошибку. Все равно придется помучиться.

Кстати, и тут создатели свифта нам помогли. У свифта есть чудесная особенность - можно делать вложенные комментарии, такие как

/*code 
/* code */ 
code*/

Это очень сильно помогает в поиске ошибок. Даже не приходит в голову никакой другой популярный язык, где разрешались бы вложенные комментарии. Может, кто подскажет?

А самое трудное найти утечку памяти, которая возникает не всегда, а время от времени. Поэтому надо любыми способами избегать ситуаций, когда утечка может возникнуть.

У свифт-программиста, слава Богу, мало тонких мест, когда могут возникать утечки памяти. Навскидку:

  1. когда объекты ссылаются друг на друга циклически.
  2. когда замыкание захватывает ссылку на объект.
  3. когда сделали что-то вроде group.enter(), а group.leave() забыли.

Может, еще что-то, но не вспоминается из практики.

Эппл пытается нам помочь в каждом непростом случае. Например, вместо классов рекомендует использовать структуры, которые передаются by value, поэтому циклических ссылок возникнуть в структурах не может. В замыканиях требуется всегда писать явно self.myVar, это тоже не случайно.

Но и программисту нужно быть предельно внимательным, когда он понимает, что есть вероятность возникновения утечки памяти. Неважно, маленькая эта вероятность или большая. Если утечка возможна, этого достаточно, чтобы обложиться со всех сторон защитой, даже если вам кажется, что это смешно. Потом будет не смешно, когда вы и ваши коллеги днями и ночами будете комментировать код кусочками, пытаясь локализовать место утечки.

Поэтому, уважаемые форумчане, не слушайте всяких проходимцев, и крайне осторожно подходите к коду, который может вызвать утечку. Используйте структуры вместо классов, если это возможно. Избегайте замыканий (если это не функции), а если используете, пишите всегда [unowned self]. Всегда проверяйте на парность group.enter()/group.leave().

И как можно чаще нажимайте в Xcode кнопочку “Debug memory graph”. Кнопочка эта очень маленькая, но крайне полезная. Чем раньше вы найдете утечку, тем лучше.

Желаю всем поменьше ошибок в коде. И не болейте, берегите себя.


#20

Перекреститесь, вдруг рефакторить станете меньше… Ну а так модульный подход/ нисходящее программирование… Ну и если TDD вдруг используете, Где бесконечный рефакторинг?

Порадовало вот это:

Кто у вас отвечал за кодревью, бухал видимо без остановки!