О ленивых методах инстанцирования и удобства - PullRequest
1 голос
/ 14 декабря 2011

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

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

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

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

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

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

  • Является ли то, что я описал, разумным подходом?
  • Правильно ли объявить свойство weak?
  • Существуют ли какие-либо проблемы с производительностью в отношении того, что я описал?Было бы лучше на самом деле вызывать экземпляр напрямую?
  • Рассмотрим ситуацию, когда у вас есть 20 классов, каждый из которых нуждается в собственном указателе на экземпляр Константы.Будет ли этот подход работать тогда?

Спасибо за ваше время.

Ответы [ 4 ]

3 голосов
/ 14 декабря 2011

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

// 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 классах.

2 голосов
/ 14 декабря 2011

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

1 голос
/ 14 декабря 2011

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

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

static Constants * defaultInstance = nil;

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

@interface Constants : NSObject
// etc.
@end

extern Constants * defaultInstance;

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

  • Является ли то, что я описал, разумным подходом?

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

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

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

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

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

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

Мне это кажется громоздким и не элегантным.

1 голос
/ 14 декабря 2011

Для константы я предпочитаю использовать .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, посмотрите ЗДЕСЬ в документации Apple в разделе Creating a Singleton Instance и внимательно посмотрите на код, который они дают для создания синглтона, который должен ответить на ваш запрос о weak or strong ссылка на него.
Но, по сути, строгая одноэлементная реализация будет иметь только один экземпляр этого класса, созданный за все время работы приложения.Таким образом, если у вас есть 100 объектов, указывающих на это, это не меняет отпечаток вашей памяти, есть только 1 синглтон, но если у вас есть 100 объектов, которые определенно повлияют на вашу память.

...