2011-12-13 3 views
1

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

В someClass, поэтому мы можем ссылаться на [Constants instance] someCleverConstant];

Typing это надоедает очень быстро, и было бы неплохо, чтобы получить быстрый доступ к экземпляру.

  • В someClass, мы можем объявить @property (nonatomic, weak, readonly) Constants *constants;
  • И геттер к экземпляру
-(Constants*) constants { 
    if (constants == nil) 
    constants = [Constants instance]; 
    return constants; 
} 

Таким образом, в SomeClass, поэтому мы можем ссылаться constants.someCleverConstant; вместо

Несколько вопросов по этому вопросу:

  • Это то, что я описал разумным путем?
  • Уверенно ли указать объект weak?
  • Есть ли проблемы с производительностью в отношении того, что я описал? Было бы лучше называть экземпляр напрямую?
  • Рассмотрите ситуацию, когда у вас есть 20 классов, каждый из которых нуждается в собственном указателе на экземпляр Constants. Будет ли этот подход работать тогда?

Благодарим за ваше время.

+0

Каковы константы? –

ответ

1

Вы можете просто создать глобальный указатель на свой синглтон, например NSApp для [NSApplication sharedApplication].

Предположительно у вас уже есть что-то вроде

static Constants * defaultInstance = nil; 

в верхней части вашего файла реализации. Если удалить static и объявить переменные в своем заголовке (сохраняя определение в файле .m):

@interface Constants : NSObject 
// etc. 
@end 

extern Constants * defaultInstance; 

Вы можете получить доступ к одноэлементному экземпляру через имя defaultInstance (вероятно, хочет изменить что хотя, хотя) в любом файле, который импортирует заголовок (который вы должны делать так или иначе). Вам нужно будет вызвать ваш метод настройки Singleton (+instance или что-то еще) где-то в самом начале вашей программы, например -applicationDidFinishLaunching, чтобы убедиться, что указатель установлен до его использования.

  • Это то, что я описал разумным путем?

Я думаю, что есть и другие, лучшие подходы, описанные выше, и в ответ Paul.s в.

  • Правильно ли объявить свойство weak?

Да, класс, который имеет этот указатель не нужно владеть ею, потому что синглтон владеет собой;

  • Есть ли какие-либо проблемы с производительностью, что я описал? Было бы лучше называть экземпляр напрямую?

В любом случае, [Constants instance]self.constants или вы делаете сообщение отправить. В первый раз, когда вы делаете self.constants, вы делаете два. Однако ничто из этого не должно быть реальной проблемой.

  • Рассмотрим ситуацию, когда у вас есть 20 классов, каждый из которых требует это собственный указатель Constants инстанции. Будет ли этот подход работать тогда?

Мне кажется громоздким и безвкусным.

2

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

1

Для постоянной Я предпочитаю использовать .h файл как этот

// ConstanteDef.h 
#pragma mark Entity Name Constante 
#define kItemInfos @"ItemInfos" 
#define kCategorie_DItems @"Categorie_DItems" 
#define kCommerce @"Commerce" 
#define kListe @"Liste" 
#define kListeItem @"ListeItem" 
#define kPrixElement @"PrixElement" 
#define kTypeDe_CommerceOuListe @"TypeDe_CommerceOuListe" 

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

@interface CoreDataController : NSObject { 

NSManagedObjectContext *leManagedObjectContext; 
NSManagedObjectModel *leManagedObjectModel; 

@private 
Commerce_MO *leCommerceAucun; 
} 
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; 
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; 

#pragma mark Objet par Défaut 
@property (nonatomic, retain, readonly) Commerce_MO *commerceAucun; 

#pragma mark Nouvel Objet 
// new = retain count = 1, celui qui commande est responsable de la mémoire. 
- (id)newMOforClass:(Class)uneClasse; // Pas le mieux, mais pourrais servir pendant le run time. Retourne nil si uneClasse ne correspond pas à quelque chose. 
- (PrixElement_MO *)newPrixElement; 
- (ItemInfos_MO *)newItemInfos; 
- (Commerce_MO *)newCommerce; 
- (Liste_MO *)newListe; 
- (ListeItem_MO *)newListeItem; 

#pragma mark Singleton call 
+ (CoreDataController *)sharedCoreDataController; 
@end 

Так что в моем коде, когда мне нужно создать новый объект Мне просто нужно, чтобы сделать это:

CoreDataController *cdc = [CoreDataController sharedCoreDataController]; 
Liste_MO * = [cdc newListe]; 

Более подробную информацию о концепции Singleton, Посмотрите HERE в документации компании Apple в разделе Creating a Singleton Instance , и внимательно посмотрите на код, который они дают, чтобы сделать синглтон, который должен ответить на ваш запрос о связи weak or strong.
Но в сущности строгая реализация одноэлементности будет иметь только один экземпляр этого класса, созданный на протяжении всего срока действия приложения. Поэтому, если у вас есть 100 объектов, указывающих на него, это не изменяет печать вашей памяти, есть только один синглтон, но если у вас есть 100 объектов, которые определенно повлияют на вашу память.

3

Следуя @vinceburn, я использовал бы следующий пример для констант и singleton для более сложных структур.

// Constants.h 
// Replace PSMyApp for something more useful. e.g. company/name initials followed by app/class 

// String example 
NSString * const PSMyAppString = @"constantString"; 

// Logically related integers 
typedef enum { 
    PSMyAppRelatedValuesOne = 0, 
    PSMyAppRelatedValuesTwo, 
    PSMyAppRelatedValuesThree 
} PSMyAppRelatedValues; 

// Float example 
const CGFloat PSMyAppFloat = 0.3f; 

// Integer that has no related values 
const NSInteger PSMyAppInteger = 2; 

Я предпочитаю это более #define как я получаю автозаполнение и проверки компилятора и он подходит более естественно с тем, как Apple, делает вещь в некоторых из UIKit классов.

+0

Вы получили завершение кода для '# define'. И для чего-либо еще, кроме строки, я остаюсь как можно дальше от #define, потому что сложнее отлаживать, как вы указали. Обычно я использую его только для 'string', которые являются частью некоторого« ключа/значения ». Чтобы избежать опечатки. –

+0

Я не знал, что это автозаполнение. Мне никогда не везло с '# define', но это может быть просто xcode. Из интереса почему вы используете '# define' для строк, а не только' extern', как в моем примере? Есть ли преимущества? –

+0

У меня нет большого фона C, и я смутился с ключевым словом 'extern' в первый раз, когда я его использовал, и в книге, которую я читал, изучая цель-C, они в основном использовали #define, поэтому я только что принял Это. Не знаю никаких преимуществ, кроме того, что я получаю автозаполнение и избегаю опечатки в строке, которую компилятор не поймал, потому что они были бы в строке, но «extern» также дает вам это. –

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