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

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

НЛО прилетело и опубликовало эту надпись здесь
Статья рассказывает о двух (имхо — совершенно) не связанных задачах и их так же не связанных решениях. Думаю было бы лучше разобрать что-то одно, но очень подробно, в техническом плане: не просто, куда нажать, чтобы заработало, а глубокий экскурс в то, как это вообще работает.

Пояснение:
Я не пользуюсь сторибордами, ксибами и строю весь интерфейс на аутолейауте с помощью KeepLayout. Сторонник мнения, что сториборды — зло. По этому вопросы могут показаться странными.

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

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

3. Что значит
Теперь таблица может работать, как будто ее загрузили из Storyboard.
? В чем отличие поведения UITableView, созданной в сториборде, от онной, созданной в коде?

4.
- (NSArray*)cellPrototypes { return nil; } //Чтобы не было warning-a
Серьезно? Вы только что все сломали. Обьясните, пожалуйста, читателям, почему класс, которому добавили аксессорный метод, возвращающий nil, когда либо будет возвращать по этому проперти не nil? Расскажите, как работает Extensions в Obj-C? Метод, который я имплементировал в Extension, когда и как добавляется в класс? Расскажите, как работает IBOutlet/IBOutletCollection для property? При загрузке из nib выполняется -setPropertyName: или же в рантайме имплементируется геттер -propertyName? Если первое, то почему нет краша, ведь поведение проперти по умолчанию это
@sythnesize propertyName = _propertyName;
, а ClassExtensions не умеет добавлять iVar'ы в класс по очевидным причинам, и для Extensions пропертя делается (скорее всего, я не компилировал такой случай на моей практике без имплементации аксессорных методов в extension, чтобы посмотреть, что будет)
@dynamic propertyName

и ожидает, что вы имплементируете свои методы, и если вы этого не сделаете, то будет краш. Если же второе, то почему ваша имплементация, если код рабочий, оверрайдится имплементацией для IBOutlet? Это противоречит ожидаемому поведению dynamic пропертей в Foundation и ко. Например NSManagedObject в CoreData. Да и о каком конкретно ворнинге речь, и почему вы просто от него отмахиваетесь?

Предложения:
5. Все связанное с высотой клеток, имхо, стоит вынести в классы самих клеток, а точнее имплементировать их суперкласс, который будет хранить «невидимые» клетки по именам классов и блоки их инициализаций, заместо нагружения лишним кодом ваш контроллер.

6.
static char cellPrototypesKey;
// ...
objc_setAssociatedObject(self, &cellPrototypesKey, cellPrototypes, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
Вы только что создали бестолковую переменную, которая торчит в скопе всего файла. Вместо этого предлагается (http://nshipster.com/associated-objects/) делать
objc_setAssociatedObject(self, @selector(getterName), cellPrototypes, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
Статья рассказывает о двух (имхо — совершенно) не связанных задачах

Действительно, вторая задача всплыла спонтанно при написании статьи. Возможно, вы правы, но статья не задумывалась как пособие для совсем новичков (о чем я честно и предупреждаю в начале), а чтобы показать как можно (если очень хочется) решить данные конкретные задачи.
А заодно возможно кому-то привести пример использования наследования, категорий(extensions), outlet-collections, и одного из способов вычисления высоты ячеек.
Почему не реализовать нужные клетки в отдельных ксибах

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

Чтобы иметь возможность проставить аутлет в Interface Builder нужна пропертя, по сути только сеттер, мы этот массив в таблице не храним и геттер нам не нужен. В категории (exntension) ivar-ы не сгенерятся, как вы верно заметили, и будет варнинг, что геттера нет, и его вызов приведет к крашу.
Все связанное с высотой клеток, имхо, стоит вынести в классы самих клеток

Согласен, иногда так лучше. Но для простых ячеек я предпочитаю не плодить сущности, а просто накидать лейблов и загружать их по тэгу (да-да, я знаю что Apple на WWDC сказала никогда-никогда так не делать, но что страшного если в ячейке 2 лэйбла?)
Вы только что создали бестолковую переменную, которая торчит в скопе всего файла

Спасибо, действительно, учту, не думал о такой реализации.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории