2009-04-26 3 views
0

Я разрабатываю приложение Cocoa (Touch), и есть определенные данные (например, информация о собственном устройстве и список мест), которые я должен сохранять между разными видами и контроллерами.Глобальные переменные как псевдонимы для одиночных чисел?

Я думал хранить его в качестве переменных экземпляра в своем делете делегата, но обращение к делегату довольно громоздко (без радости набирать [[[UIApplication sharedApplication] delegate] locations] каждый раз, когда я хочу получить доступ к массиву местоположений, и это много мест), поэтому я подумал о вводя какой-то псевдоним (a la NSApp) для делегата, но, кроме NSApp, я не видел этого очень часто в других приложениях Cocoa.

Я также подумал о том, чтобы идти дальше и вводить псевдонимы для моих одноэлементных классов, поэтому вместо [State sharedState], почему бы не переименовать класс в _State и сделать один экземпляр его именем State?

ответ

0
#define FOO [[[UIApplication sharedApplication] delegate] locations] 
+0

Да, определение - хорошая идея. Может быть, с литой, чтобы избежать предупреждений. – esad

1

Возможно, я бы написал такой класс, как LocationManager, который дал синглтон с [LocationManager sharedManager] или аналогичным. Вызов через делегат прерывает инкапсуляцию (и вы вызываете через 3 объекта). Даже стиль NSApp #define не исправляет это.

+0

Местоположение - это просто простой массив объектов «Местоположение», поэтому не будет вводить «LocationManager» слишком много накладных расходов? Я имею в виду, мой вызов будет тогда [[LocationManager sharedManager] location] ', который не является более компактным. Может быть, статическая переменная, удерживающая этот массив, доступ к которой можно получить через '[Список местоположений]' и '[Location setList:]' – esad

1

Основная цель использования вызова метода для получения синглета - это то, что синглтон можно лениво подготовить. Например:

static State sharedStateInstance; 

@implementation State 
+ (id)sharedState { 
    if (!sharedStateInstance) 
     sharedStateInstance = /* Allocate instance */; 
    return sharedStateInstance; 
} 
@end 

Таким образом, это означает, что если нет кода никогда не вызывает +sharedState, никакие ресурсы не тратятся его создания.

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

1

Существует несколько причин, по которым Cocoa поощряет использование [Foo sharedFoo], а не глобального объекта Foo.

[Foo sharedFoo] может автоматически создать экземпляр при первом использовании.

Именование экземпляра с большой буквы очень сбивает с толку, потому что он выглядит как класс, поощряющий ошибки. Согласованность в наименовании лежит в основе хорошей цели-C. Компилятор не может защитить вас от множества ошибок, поскольку ObjC очень динамичен. Хорошее именование и самодисциплина в последовательности - вот что приводит к отсутствию ошибок в Cocoa.

параллелизм:

Foo *foo = [Foo sharedFoo]; 
Foo *foo = [[[Foo alloc] init] autorelease]; 
Foo *foo = [Bar fooAtIndex:0]; 

Все три из них могут быть законными в той же программе. Просто потому, что есть одноэлементный экземпляр, это не означает, что других экземпляров тоже нет. Наглядным примером этого является NSNotificationCenter. Это синглтон, но вы можете сделать дополнительные экземпляры (и есть причины сделать это).

Глобальная переменная может быть изменена глобально. A sharedInstance быть не может. Например, если State является глобальной переменной (а не классом), то State=nil является законным в любой точке программы. Это разрушает инкапсуляцию и является простой опечаткой для state=nil, которая не может быть захвачена компилятором. Если State - это класс, то компилятор может поймать эту легкую ошибку.

Многие правила присвоения какао существуют для поощрения высоко читаемого кода и сведения к минимуму ошибок в высокодинамичной и слабо типизированной среде.Как и у Perl's use strict, мы должны быть очень осторожны, прежде чем отказаться от какой-либо небольшой системы безопасности, которую мы имеем.

+0

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

+1

Если вы часто обращаетесь к делегату приложения, возможно, вы слишком сильно его повесили. Многие вещи, которые висели на делегате приложения, должны быть переданы другим объектам или должны быть одиночными. Тем не менее, мне не нравится #define (поскольку это затрудняет работу с отладчиком), это не всегда неправильно, если вы хорошо назовете. Например, я использовал делегат #define AppDelegate [[UIApplication sharedApplication]]. Ваш FOO-определитель, вероятно, будет одобрен, если бы он назывался SharedLocations. Тем не менее, Cocoa настоятельно поощряет легко читаемые и понятные по сравнению с краткосрочными. –

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