Как стать автором
Обновить

Комментарии 18

Спасибо, что поделились реальным опытом использования. Live rendering сыроват местами, но пользоваться можно. Думаю, в XCode 7 будет намного лучше :)
НЛО прилетело и опубликовало эту надпись здесь
Эти плагины с Cocoa Touch не дружили, если мне не изменяет память.
А что на счет упомянутой iOS 8? На проекте с таргетом 7+ в Xcode 6 не будет работать?
Рендериться будет в iOS 8-симуляторе в любом случае, deployment target безразличен, насколько я понял.

У меня вообще проект с deployment target 6.0.
Это вы вот про это?
Суть такова: Xcode собирает ваше приложение с указанием специальных дефайнов, симулятор загружает приложение как динамическую библиотеку и инстанциирует ваш наследник UIView, чтобы его отрендерить, и передает результаты обратно в Xcode через XPC.


Надо попробовать будет. Спасибо за опыт.
Да, вьюшка рендерится в невидимом симуляторе, который отдает в Interface Builder картинку.
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [self.class xxx_viewFromNib];
    self.frame = frame;
    return self;
}


А вот здесь у вас не будет двойного выделения памяти?
Ведь перед вызовом initWithFrame: разработчики вызывают alloc, а далее у Вас внутри вызывается метод класса [self.class xxx_viewFromNib], который возвращает новый объект. В результате изначальный alloc не имеет смысла.
Да, будет двойное выделение памяти, изначально выделенный участок памяти будет тут же освобожден. Учитывая, что UIView — достаточно легковесный объект (действительно «тяжелой» его частью является только backing store связанного CALayer, но его не может существовать до первой отрисовки, а тем более до вызова -init...), я бы не стал из-за этого беспокоиться, пока это действительно не станет бутылочным горлышком.

В общем-то все, что реализовано по паттерну class cluster в Cocoa как-то так и работает. Буду рад ошибаться.
Хотя нет, с class cluster можно организовать более эффективную схему, переопределив +allocWithZone: у корневого класса, чтоб он возвращал всегда один и тот же объект-плейсхолдер, тут так не получится.
Все равно это мягко говоря «костыльно». По сути здесь наблюдается таже проблема, что и раньше: нельзя ложить в xib вью, которая реализована в другой xib.
Решалось это двумя способами:
1. Не использовать xib для вашей вью;
2. Добавлять вашу вью в коде, а не в xib.

IB_DESIGNABLE компоненты должны быть реализованы в коде, без использования xib.
3. использовать storyboard embed segue и UIVIewController вместо UIView ;)

Если уж так не нравится «костыль», можно обернуть его в #ifdef/#endif, чтоб -initWithFrame: присутствовал только в режиме live rendering.

IB_DESIGNABLE компоненты должны быть реализованы в коде, без использования xib.

Это где-то прямым текстом в докуентации Apple написано?
Не знаю, написано ли там это. Я сделал такой вывод исходя из того, что Вы написали в статье.
Возможно я выразился слишком обобщенно. Нужно было сказать так:
«Исходя из информации в статье IB_DESIGNABLE компоненты нужно реализовать в коде, без использования xib, иначе будет выполняться двойное выделение памяти, что само по себе неправильно. Неважно 1 байт это или 1 мегабайт.»

По поводу #ifdef/#endif, не понял как это поможет решить проблему в runtime.
А нельзя как то IB_DESIGNABLE обернуть в #ifdef? А то получается какая то ерунда, бандл меняется, вообще лучше бы не было этих аттрибутов… Или это только в симуляторе? Вообще я так и не понял, зачем что то передавать из симулятора в ХCode, ведь этот аттрибут нужен только для отображения в IB…
IB_DESIGNABLE влияет только на live rendering, и вся эта чехарда с бандлами тоже актальна только при live rendering. Просто так у вас в коде ничего не сломается.

Поясню про «передавать из симулятора в Xcode»:
  1. Вы открываете в IB xib/storyboard, который содержит view, поддерживающий live rendering
  2. Xcode собирает ваш проект в отдельную папочку
  3. Xcode запускает в фоне симулятор iOS и просит его отрендерить view такого-то класса (который можно найти в бинарнике, полученном в п. 2) с такими-то параметрами
  4. Симулятор рендерит вьюшку и отправляет обратно в Xcode изображение
По п. 3 еще поясню: собственно там и происходит «магия» с бандлами, так как ваше приложение не запускается как обычно, а загружается как динамическая библиотека.
Спасибо за пояснения, теперь понятно. Ну в таком случае вроде как ничего страшного нету.
Вот хорошая статья про то же самое на Swift
justabeech.com/2014/07/27/xcode-6-live-rendering-from-nib/

Там обходят проблему Swift
Должен заметить, что в Swift такой трюк не пройдёт (так как там initializers похожи на конструкторы в Java или C++, то есть не могут подменить инициализируемый объект другим).

путем двойного вкладывания
CustomView
    CustomView
        UIImageView
        UILabel
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации