Как стать автором
Обновить
15
0
Кирилл @ws233

Руководитель мобильной разработки

Отправить сообщение

Вот и настало то время, когда можно писать статьи на Хабре и выступать на митингах о своем собственном процессном фреймворке, который решает все проблемы, имеющиеся в *Подставь сюда свой самый ненавистный процессный фреймворк*.

Одно время был бум архитектурных реализаций.

А теперь катится волна процессных фреймворков.

К статье вопросов нет. Наоборот, всячески поддерживаю, когда люди пытаются разобраться, а почему же у всех работает, а у них нет. Но я так и не получил ответа из вступления, а что же помешало автору в последующем пользоваться фреймворком, тем более, что успешный опыт у него был? Команда? Люди? И как исправлять-то причину?

Но, это же будет противоречить и опыту и описанию Apple'а. Я четко вижу в своих приложениях, как память уменьшается, когда у меня еще есть unowned ссылки, но уже нет strong ссылок.

Это как-то можно объяснить?

Но погодите. У меня что-то не сходится.

HeapObject - это и есть выделенный нами объект, правильно? Вернее обязательная часть нашего объекта, содержащая isa и счетчик ссылок (ну или ссылку на side table). Верно? дальше за этой обязательной частью лежат хранимые переменные нашего объекта. И вот это все вместе - наш объект. Правильно?

Теперь, если у нас счетчик сильных ссылок стал равен 0, то мы можем освободить всю эту конструкцию из памяти, т.к.она нам не нужна. Но получается, что мы ее не можем освободить, т.к. нам нужна side table, по которой мы сможем сказать, что вот такой-то объект больше не существует. Т.е. получается, что объект живет в памяти не до тех пор, пока на него не осталось сильных ссылок, а он живет пока на него есть вообще хоть одна ссылка или хотя бы пока на него не осталось даже unowned ссылок? Ваша цитата: "А unowned счетчик отмеряет время жизни памяти, выделенной под объект." говорит об этом же?

Но погодите, тогда это полностью противоречит тому, что нам дает Apple. Точно ошибки в понимании логики нигде не произошло?

И второй вопрос. Какие прикладные задачи теперь можно решать с этим знанием в финтех-проекте? Вы же не просто ради спортивного интереса реверс-инжинирили компилятор? :)

Статья мощная. Но остались нераскрытые вопросы.

А зачем же нам счетчики weak и unowned ссылок? Со strong понятно -- это счетчик жизни объекта, по нему мы понимаем, жив объект или уже мертв. А зачем считать weak и особенно unowned. Допустим, что weak нужен просто для валидации, что мы нашли в памяти нужное число ссылок для их обнуления. Хотя зачем может быть нужна такая валидация? А вот про unowned вообще не могу предположить, зачем...

Есть у Вас ответы на эти вопросы?

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

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

Спасибо. Статья интересная. Ждем продолжения.

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

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

Кажется, что единый Стейт все же не решает проблемы многопоточности, ну вот никак. Даже с единым стейтом вы все равно не застрахованы, что ваше приложение не окажется в конкретный момент времени в непредусмотренном состоянии. Даже с единым стейтом, система в любой момент времени может перекинуть вас на другой поток. Даже во время вашего перехода из одного стейта в другой, пока этот самый Стейт еще не обновился полностью. И вы получите тот же самый рассинхрон, которого Вы так опасаетесь. Проблему мог бы решить единственный поток, в котором и происходят все смены состояний и их чтения, но мы прекрасно знаем, что в iOS работать в одном единственном потоке практически невозможно. А значит, единый Стейт для Вас - это лишь попытка себя обмануть. Кажется, что единственный возможный выход из данной проблемы - это правильная работа в многопоточной среде с атомарными записями и чтениями состояния. И тут уже не важно, единый у вас Стейт или распределенный, но обеспечивающий атомарность записи и чтения. Тем более, что Вы тоже согласны, что Стейт в Redux не обязан быть единым. Кажется, что единый Стейт обеспечивал бы те плюсы, что Вам нужны, в каком-то другом программерском мире, но не в иосном. Возможно, я ошибаюсь.

Подскажите, а почему State единый и такой массивный? Чем это обусловлено? Кажется, что если просто поделить один божественный State на кучу мелких, но подписывающихся друг на друга, большая часть ваших проблем, если не все, уйдут. Тот же профиль вы выделяете в отдельную сущность, за которой потом следит тот, кому нужен профиль, без слежения за всем "богом". Кажется, что в Redux не должно быть ограничения на то, что состояние обязано быть одним. Но даже если и так, можно же завести под каждый UI-компонент свой фасад, который будет под собой объединять по нужной Вам логике отдельные независимые стейты. Кажется, что корень проблем модуляризации у Вас -- это попытка затянуть God-объект, связывающий в большой клубок все ваще приложение, в модульную архитектуру. Кажется, что так не выйдет. Модуляризация подразумевает в том числе разнесение модели и стейта на независимые куски.

В чем на Ваш взгляд заключается усложнение?

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

Спасибо. Снова хорошие мысли.

Вопрос контроля. Не смотрел на проблемы собственных реализаций с этой стороны. А ведь действительно. Многие могут реализовывать свои решения потому, что не понимают, как управлять тем, что есть у Apple. Что касается управления кешом через dataTask, так я, наверное, и не знаю-то, как это делается в деталях ^.^ Вы тоже натолкнули меня на хорошие мысли, спасибо за это.

Ну, и желаю Вам опубликовать статью по итогам исследований нативного кеширования. Материала должно набраться много и очень толкового.

Снова спасибо. Опять хороший ответ.

Итак, зафиксируемся:
1. dataTask умеет кешировать запросы из коробки
2. dataTask можно использовать для загрузки небольших изображений. Нигде явного лимита не указано. И лимит этот косвенно можно выявить из других признаков и рассуждений (хоть и не тех, что вы привели, по моему мнению, но об этом уже не будем).
вы с этим согласны.

Но вы опасаетесь, что dataTask сохраняет ВСЮ загруженную информацию сразу в память, что по Вашему мнению может привести к закрытию приложения системой. Вы, видимо, зацепились за первое предложение из вот этой ссылки, что сами и предоставили.

Ок, давайте разбираться.

Мы же с Вами уже разобрались, что dataTask кешурет данные. Т.е.они все же складываются на диск. А раз они складываются на диск, то с диска же они и читаются в оперативную память. Так? Уверен, что так.

Давайте теперь разберемся, а как же они читаются? А читаются они стандартным для iOS способом, применимым повсюду. Через NSData. В этом можно убедиться в конкретном примере, посмотрев тип данных первого параметра замыкания, вызываемого в результате выполнения dataTask.

Что ж открываем документацию, читаем:

The size of the data is subject to a theoretical limit of about 8 exabytes (1 EB = 10¹⁸ bytes; in practice, the limit should not be a factor).

Переведу и поясню. Теоретически, размер буфера в NSData ограничен 10ю в 18й степени (безумное число), а практически, вы не должны заботиться об этом лимите. Все работает для вас с такими объемами.

Как Вы думаете, как Apple удалось такого достичь на мобильных телефонах с гораздо-гораздо меньшим объемом оперативной памяти?

Все верно! Буфер NSData хранится на диске, а не в оперативной памяти. Это очень легко проверить, открыв какой-нить фильмец на пару гигабайт размером через NSData.

Таким образом, первое предложение, за которое вы зацепились, значит не что иное, как то, что данные вам возвращаются в виде объекта NSData, с которым вы можете работать, как-будто они находятся в оперативной памяти. Вам просто не нужно это делать самостоятельно, как если бы вы работали с downloadTask.

Что же касается замечания о том, что надо конструировать UIImage. Так он (как и Image в Свифт) работает поверх NSData все с тем же механизмом. Я это четко осознал, когда бил на тайлы 100МБ jpeg военную карту Москвы на 4S. Просто прикиньте, какой размер эта карта занимает попиксельно после декодирования jpeg. И тем не менее данная карта прекрасно отображалась на экранчике мобильного телефона. Правда, плохо масштабировалась, что я позже и решал тайлингом.

Таким образом, ваши опасения о том, что dataTask истратит всю вашу оперативную память, выглядят сомнительно. В Apple не глупые люди сидят и все для вас они уже сделали. Смысла повторять их работу я пока не увидел.

Есть еще аргументы для меня и сообщества в пользу ручного кеширования и повторения работы Apple самостоятельно вместо того, чтобы взять коробочное решение?

Хорошее пояснение, спасибо. А есть у Вас ссылки соответсвующие? И еще вопрос, а где-то указан этот барьер между небольшим и большим количеством данных? Бывают же и джейсоны на пару мегабайт, и картинки на сотни или даже десятки килобайт. Т.е.похоже, что тут не столько на размер надо обращать внимание, сколько на применимость как раз. Т.е.если нужен Кеш, пожалуйста, бери себе dataTask, нет? Ну, и если я буду использовать dataTask, а не downloadTask, Apple может зареджектить? Есть у вас чуть больше инфы на эту тему? Сам хочу разобраться.

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

Но ведь NSURLSession уже умеет работать с NSURLCache. И на самом деле городить свое собственное кеширование смысла нет. Достаточно правильно настроить кеширование запросов сессии (с обеих сторон: клиентской и серверной) и тупо дергать каждый раз запрос -- первый раз он скачает инфу с сервера, дальше будет брать из кеша, пока этот Кеш не почистится системой или не инвалидируется. просто и легко.

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

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

Думаю, с этой информации и стоило начинать статью, чтобы помочь читателю правильно выбрать инструмент.

Евгений, по прошествии 3х лет что бы Вы могли добавить по теме геймификации рабочего процесса?

Наигрались ли ребята?

Какие проблемы возникли, если возникли?

Расширили ли Вы практику на большее число команд или практика умерла сама собой?

Перенял ли ее кто-то из коллег-руководителей? Какой был у них опыт? С чем они столкнулись? Взлетело ли у них?

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Работает в
Дата рождения
Зарегистрирован
Активность