Жизнь программирования и отладки — как выглядит действительно серьезная ошибка, найденная и исправленная. Сказка для основателей стартапов, разработчиков и любопытных.

Так выглядит отчаяние.

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

Случайно заметив ошибку — вы начинаете с записи просто обстоятельств и действий, которые вы помните, когда вы заметили ее. В чем я был уверен, так это в том, что я начал с образца (из нашего списка избранных встроенных сенсорных грамм) и что проблема возникла после того, как я отредактировал текст на первой странице.

Обратите внимание, что я сообщил, что экран воспроизведения был полностью черным на 2-й странице.

Этот журнал тестирования показывает немного больше прогресса в воспроизведении. Параметр без полного предварительного просмотра относится к поведению страницы текстового редактора — он показывает шрифт и размеры, которые вы выбрали, либо в виде простого образца, либо только шрифта в этом стиле, либо в виде полного предварительного просмотра. режим, в котором он отображается на фоне. Я также улучшил свое понимание — исходная полностью черная страница теперь явно фон не изменился. Тестирование с использованием различных образцов показало, что первоначальный тест был полностью черным только потому, что на первой странице был сплошной черный фон. Другие тесты, которые начинаются с фонового изображения, сохраняли изображение видимым.

Несколько дней поисков в тупиках…

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

Эта надежда не совсем безнадежна.

Среди многих редакторов элементов подробностей в Touchgram есть еще один, который делает некоторые похожие вещи. Он представляет собой часть Touchgram в SKView, но никогда не имел такого побочного эффекта. Так что есть также вероятность, что я смогу выяснить, какая именно разница между этими двумя экранами заставляет один вызывать эту ошибку, а другой избегать ее.

Назначив максимально возможную баунти-баунти для этого вопроса и неоднократно публикуя его в Твиттере, вы не получили никакого совета, только 70 человек просмотрели отчет об ошибке.

История

После года масштабного расширения основных возможностей Touchgram я полировал релиз и случайно заметил ошибку.

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

Но иногда вы просто натыкаетесь на вещи.

Если вам повезет, вы заметите это вовремя, имея достаточно контекста, чтобы воссоздать проблему.

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

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

Ответ

Сравнение экранов не дало ответа, проблема была слишком косвенной для этого.

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

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

Программисты будут бить себя по голове и кричать или смеяться, когда увидят это.

// in a method called from viewWillAppear, calling a simple drawing kit created by PaintCode
self.thicknessSwatch.drawer = { 
  self.hasThickness ? 
    LinePickerKit.drawEdgeThickness() : 
    LinePickerKit.drawNoEdge() 
}

Это фиксированная версия:

self.thicknessSwatch.drawer = {
  [weak self] in (self?.hasThickness ?? false) ? 
    LinePickerKit.drawEdgeThickness() :
    LinePickerKit.drawNoEdge() 
}

С технической точки зрения, первая версия отвечает за цикл сохранения. Это означает, что даже если экран, содержащий эту логику, больше не виден, его нельзя очистить из памяти. Часть цикл связана с тем, что один элемент на экране ссылается на другой. В большинстве случаев каждый экран в приложении содержит сотни ссылок на элементы управления и логику, но все они являются односторонними ссылками. Таким образом, когда экран удален, операционная система может безопасно удалить все. С циклом у iOS нет возможности узнать, безопасно ли разорвать эту зависимость.

Почему это было трудно найти?

Это своего рода ошибка идеального шторма.

Природа Touchgram, работающего в приложении Apple Messages, затрудняет запуск некоторых инструментов, которые автоматически обнаруживают такие проблемы.

Я занимаюсь поэтапной разработкой, обычно за несколько часов я могу увидеть, что незначительные изменения вызвали проблемы. Однако оскорбительный код был написан несколько месяцев назад. Это почти не имеет никакого эффектаединственным проявлением цикла сохранения была ошибка, показанная здесь.

Побочный эффект Apple от моей ошибки применим только к многостраничным Touchgrams, которые имеют эффект перехода между страницами. Многие из моих тестовых материалов одностраничные, а многостраничные не всегда имеют переходы. Это сделало ошибку относительно случайной. Как описано ранее в статье, потребовалось много тестов, чтобы выявить последовательный шаблон.

Побочный эффект был очень редким, и только один случай был четко описан в Интернете. Это было описано как ошибка iOS 9, но, скорее всего, была неправильно охарактеризована при обстоятельствах, подобных тем, с которыми я столкнулся. Да, я сказал iOS 9 — единственный человек, который описал эту ошибку, сделал это пять лет назад.