About lazy creation methods and convenience

Suppose you have a Singleton Constants class whose instance you want to use throughout the application.

In someClass , so we can reference [Constants instance] someCleverConstant];

Typing gets old very quickly, and it would be nice to get a shortcut for the instance.

  • In someClass we can declare @property (nonatomic, weak, readonly) Constants *constants;
  • And getter for instance
 -(Constants*) constants { if (constants == nil) constants = [Constants instance]; return constants; } 

So in someClass we can instead of constants.someCleverConstant; refer

A few questions on this subject:

  • Have I described a reasonable approach?
  • Is declaring the weak property correct?
  • Are there any performance issues regarding what I described? Would it be better to name the instance directly?
  • Consider a situation where you have 20 classes, each of which needs its own pointer to an instance of Constants. Will this approach work then?

Thank you for your time.

+1
source share
4 answers

You can simply create a global pointer to your singleton, such as NSApp for [NSApplication sharedApplication] .

Presumably you already have something like

 static Constants * defaultInstance = nil; 

at the top of your implementation file. If you remove static and declare a variable in your header (saving the definition in a .m file):

 @interface Constants : NSObject // etc. @end extern Constants * defaultInstance; 

You can then access the singleton instance using the defaultInstance name (you probably want to change this name) in any file that imports the header (which you should do anyway). You will need to call your Singleton configuration method ( +instance or something else) somewhere at the beginning of your program, such as -applicationDidFinishLaunching , to make sure the pointer is set before using it.

  • Have I described a reasonable approach?

I think there are other, more effective approaches described above and in Paul's answer.

  • Is declaring the weak property correct?

Yes, the class that has this pointer does not need to own it, because singleton owns it;

  • Are there any performance issues regarding what I described? Would it be better to name the instance directly?

In either case, [Constants instance] or self.constants you send the message. The first time you do self.constants , you do two. However, none of this should be a real problem.

  • Consider a situation where you have 20 classes, each of which needs its own pointer to an instance of Constants . Will this approach work then?

To me it seems cumbersome and ridiculous.

+1
source

Following @vinceburn, I would use the following example for constants and singleton for more complex structures.

 // Constants.h // Replace PSMyApp for something more useful. eg 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; 

I prefer this over #define , since I get auto-completion and compiler checking, and it more naturally matches the way Apple does things in some UIKit classes.

+3
source

This seems like a lot of work to get around just using a global variable or function. I think any of these is more reasonable.

+2
source

For constant, I prefer to use a .h file like this

 // 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" 

For now, I'm using Singleton to return a more complex element to me.
Here is one single I made to simplify my life with basic data, instead of rewriting the same code everywhere.

 @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 

So, in my code, when I need to create a new object, I just need to do this:

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

For more information on the Singleton concept, see HERE in the Apple documentation in the Creating a Singleton Instance section and carefully look at the code that they represent giving a singleton that should answer your request for a weak or strong link to it.
But in essence, a strict singleton implementation will have only one instance of this class, created for the entire duration of the application. Therefore, if you have 100 objects pointing to it, this does not change the print of your memory, there is only one singleton, but if you have 100 objects that will definitely affect your memory.

+1
source

All Articles