Почему Apple не позволяет подклассифицировать UINavigationController? И каковы мои альтернативы подклассу?

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

Увидев, как Apple говорит в своей документации по iPhone, что не следует подкласса UINavigationController, и, кажется, что-то ломается, когда это происходит, мне интересно, как мне следует расширить функциональность UINavigationController's без подкласса и, вообще говоря, как нужно работать с ограничениями подкласса при разработке Cocoa.

Спасибо!

Ответ 1

Для справки обратите внимание, что с iOS 6 UINavigationController может быть подклассифицирован на законных основаниях.

Этот класс обычно используется как есть, но может быть подклассифицирован в iOS 6 и более поздних версиях. Ссылка на класс UINavigationController

Конечно, это не значит, что вы всегда должны. Но вы можете.

Ответ 2

Почему вы хотите, чтобы UINavigationController выступал в качестве источника данных для таблицы? Вся точка UITableViewController заключается в том, что вы подклассифицируете ее, и она действует как источник данных для UITableView, который он также помещает в родительское представление и заполняет его.

Ответ 3

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

В принципе нет причин, по которым вы не можете подклассифицировать контроллер UINavigation, чтобы добавить на него полностью ортогональный слой данных, потому что он не имеет ничего общего с пользовательским интерфейсом или поведением, которым управляет UINavigationController (что касается Apple, то вы будете возиться с). Для тех, кто не согласен с этой идеей, подумайте об этом как о хранилище данных для каждой вкладки, чтобы все страницы на вкладке могли получить доступ, а не каждую страницу в системе, которая должна перейти в AppDelegate, или иметь кучу синглетов. Ну в основном это синглтон, но, по крайней мере, тот, который уже существует, и автоматически передает ссылку.

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

Ответ 4

Как я понимаю, подклассы не поощряются, потому что Objective C позволяет подклассу слишком много доступа к внутренним работам своего суперкласса.

Предлагаемая альтернатива написанию подкласса - это написать делегат, в данном случае UINavigationControllerDelegate. Затем вы можете инкапсулировать конкретное поведение, которое хотите расширить, в этот класс делегата и связать его с UINavigationController всякий раз, когда вам это нужно.

Ответ 5

Если доступная контрольная иерархия не удовлетворяет вашим потребностям с точки зрения обработки данных (мое предположение, поскольку мы не знаем, почему вы хотите, чтобы один объект был источником данных для нескольких видов), вы всегда можете создавать дополнительные данные и/или классов контроллера (как минимум, подклассы NSObject).

У вас могут сохраняться данные или другой объект при изменении видов различными способами. (1) свойство класса делегата приложения. Любой объект в вашем приложении может получить экземпляр делегата приложения с помощью

[[UIApplication sharedApplication] delegate]

Используйте это экономно, поскольку он по существу создает глобальные переменные.

(2) Вы можете передавать данные или другие объекты с контроллера на контроллер, когда вы нажимаете подклассы контроллера представления или выводите их внутри вкладок.

(3) Core Data - это еще один способ, но требуется много Cocoa под вашим поясом, и вам все равно придется управлять экземплярами контекста.

Ответ 6

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