2012-03-07 4 views
5

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

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

Итак, некоторое время спустя я решил перенести мою ту же реализацию в категорию в UINavigationController (в конце концов, он обрабатывает переходы!), Сохранил исходные классы для сравнения, и мне интересно, какой из методов будет работать лучше всего. Полностью протестировав обе версии, я могу без всяких сомнений сказать, что они равны во всех отношениях, включая скорость, точность, гладкость, частоту кадров, использование памяти и т. Д., Так, какой из них «лучше» в смысле общей ремонтопригодности?

EDIT: после прочтения хорошо написанных аргументов, которые вы все сделали, я решил использовать синглтон. @JustinXXVII сделал самый убедительный аргумент (IMHO), хотя я считаю каждый ответ здесь одинаково заслуживающим внимания. Спасибо всем за ваше мнение, я ответил на все вопросы в вопросе.

+0

Не знаете, почему ответчики на этот вопрос, похоже, не понимают, что такое категория. Это часть языка Objective C: http://macdevelopertips.com/objective-c/objective-c-categories.html – johnbakers

+0

@ThomasW, Категории - это способ расширить классы ObjC. Хотя в старые времена (ObjC1) они использовались для обработки тех вещей, которые мы используем на сегодняшний день, они являются отдельной (и очень полезной). Https://developer.apple.com/library/ios/#documentation/cocoa/ концепт/objectivec/главы/occategories.html –

ответ

3

Я сделаю корпус для одного объекта. Синглтоны используются во всем UIKit и iOS. Одна вещь, которую вы не можете делать с категориями, - это добавить переменные экземпляра. Есть две вещи, об этом:

  1. MVC рабочие процессы не переносят объекты с глубоким знанием других объектов
  2. Иногда вам просто нужно место, чтобы ссылаться на объект, который на самом деле не принадлежат нигде

Эти вещи противоречат друг другу, но добавленная способность сохранять переменную экземпляра, которая на самом деле не имеет «владельца», - это то, почему я предпочитаю синглтон.

У меня обычно есть один одноэлементный класс во всех моих проектах XCode, который используется для хранения «глобальных» объектов и выполнения мирских вещей, которые я не хочу обременять своим AppDelegate.

Примером может быть сериализация/архивирование объектов и разборки/восстановление. Я должен использовать один и тот же метод для нескольких классов, я не хочу распространять UIViewController с помощью некоторого метода сериализации для записи и чтения произвольных файлов. Может быть, это мое личное предпочтение.

Мне также может потребоваться быстрый способ поиска информации в NSUserDefaults, но я не хочу, чтобы всегда писать [[NSUserDefaults standardUserDefaults]stringForKey:@"blah"], поэтому я просто объявлю метод в своем одиночном тоне, который принимает строковый аргумент.

До сих пор я не слишком много думал об использовании категории для этих вещей. Одно можно сказать наверняка, но я бы предпочел не создавать экземпляр нового объекта сто раз, чтобы выполнить одну и ту же задачу, когда у меня может быть только один живой объект, который стоит вокруг и будет заботиться о вещах для меня. (Без обременения AppDelegate)

+0

Теперь есть ответ! – CodaFi

+0

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

6

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

Потому что, если вы уже используете UINavigationController, не имеет смысла создавать новый класс, который будет управлять только переход, как вы сказали: (after all, it handles transitions!)

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

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

1

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

+ (MyClass*) sharedInstance 
{ 
    static MyClass *instance = nil; 
    if (instance == nil) instance = [[MyClass alloc] init]; 
    return instance; 
} 

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

Дело в том, что это единственное требование к singleton. Роль метода доступа заключается в том, чтобы убедиться, что существует только один экземпляр, а не то, что он обеспечит доступ к этому экземпляру всюду. Это только побочный эффект шаблона, который, будучи асинхронным, статическим, каждый может получить доступ к этому одиночному объекту без ссылки на него (указатель) априори. К сожалению, этот факт широко злоупотребляют программистами Objective C, и это приводит к испорченному дизайну и ненависти к одноэлементному шаблону, о котором вы говорили. Но в целом это не вина, что синглтон-паттерн, но неправильное использование их метода доступа.

Теперь вернемся к вашему вопросу: если вам не нужны статические/глобальные переменные в вашем пользовательском коде перехода (я думаю, вы этого не сделаете), то ответ определенно подходит для категорий. В C++ вы должны подклассы из какого-то родительского класса BaseTransition и реализовать свои фактические методы рисования. Объектив C имеет категории (которые, на мой взгляд, являются другим способом, который легко испортил дизайн, но они намного удобнее), где вы можете добавить настраиваемые функциональные возможности, даже обращаясь к переменным вашего класса хоста. Используйте их каждый раз, когда вы можете выкупить с ними одиночные игры и не использовать синглтоны, когда основное требование к вашему классу не в том, что это будет всего лишь один экземпляр.

2

В этой реализации, для которой нет необходимости использовать Singleton, не может быть никакой разницы. Это не значит, что их нет.

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

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

В вашем случае, однако, может быть намного проще использовать Категорию. Реализация проще и вам (возможно) нужно меньше кода.

Но если вы должны были создать диспетчер данных, который содержит массив объектов, которые вы ТОЛЬКО хотите получить в одном месте, Категория не будет соответствовать задаче. Это типичная задача Синглтона. Singeltons являются объектами с одним экземпляром (и если они сделаны статическими, доступны почти везде). Категории являются расширениями для ваших существующих классов и ограничены классом, который он расширяет.

Чтобы ответить на ваш вопрос; выберите категорию.

* Подкласс может также работать, но имеет свои плюсы и минусы

2

Почему вы не просто создать базу UIViewController подкласс и расширяющие все контроллеры зрения от этого объекта? Для этой цели категория не имеет смысла.

+0

Плотный график выпуска + 108 классов и counting = будут работать над этим позже. – CodaFi

+0

Найти и заменить? ": UIViewController" с ": BaseViewController". – Sam

+0

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

3

Я думаю, что реальный вопрос в «дизайн» (как вы сказали, как коды работают нормально), и записывая вашу проблему в простых предложениях, вы найдете ответ на свой вопрос:

  • Синглтон Цель состоит в том, чтобы иметь только один экземпляр класса, запущенного в вашем приложении. Таким образом, вы можете делиться вещами между объектами. (доступно одному для многих объектов)

  • Цель категории - расширить методы, доступные для a класс. (Доступен один класс объектов только! Ок ... объекты подклассов тоже)

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

Мое мнение таково, что то, что вы хотите достичь, покрывается категорией, и, делая это, вы гарантируете, что только объекты, которые обращаются к этому методу, имеют право использовать его. С шаблоном singleton любой объект любого класса мог бы назвать ваш синглтон и его методы (и ... он мог работать без знания того, как для версии ОС n, но ваше приложение может быть разбито на версию n + 1).

Смежные вопросы