关于惰性实例化和便捷方法

时间:2011-12-13 23:57:35

标签: objective-c lazy-initialization convenience-methods

假设您有一个Singleton常量类,您希望在整个应用程序中使用该实例。

someClass中,我们可以参考[Constants instance] someCleverConstant];

键入此内容会变得非常快,获得实例的快捷方式会很不错。

  • someClass中,我们可以声明@property (nonatomic, weak, readonly) Constants *constants;
  • 实例的吸气剂
-(Constants*) constants {
  if (constants == nil) 
    constants = [Constants instance];
  return constants;
}

这种方式在someClass中,因此我们可以引用constants.someCleverConstant;而不是

关于此的一些问题:

  • 我所说的是一种合理的方法吗?
  • 声明属性weak
  • 是否正确
  • 我所描述的是否有任何性能问题?实际上直接调用实例会更好吗?
  • 考虑一种情况,你有20个类,每个类都需要它自己的指向常量实例的指针。这种方法会起作用吗?

感谢您的时间。

4 个答案:

答案 0 :(得分:3)

关注@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类中做事的方式。

答案 1 :(得分:2)

使用全局变量或函数似乎需要做很多工作。我认为其中任何一种都是更合理的方法。

答案 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概念的更多信息,请在Creating a Singleton Instance部分的Apple文档中查看HERE,仔细查看他们为编写单例而提供的代码,该代码应该回答您关于{的问题。 {1}}链接到它。
但实质上,严格的单例实现只会在应用程序的整个持续时间内创建该类的一个实例。因此,如果你有100个指向它的物体不会改变你的记忆足迹,那么只有1个单身,但如果你有100个对象肯定会影响你的记忆。

答案 3 :(得分:1)

你可以创建一个指向单身的全局指针,例如NSApp的{​​{1}}。

据推测,你已经有了像

这样的东西
[NSApplication sharedApplication]

位于实施文件的顶部。如果删除static Constants * defaultInstance = nil; ,并在标题中声明变量(将定义保留在.m文件中):

static

然后,您可以通过名称@interface Constants : NSObject // etc. @end extern Constants * defaultInstance; 访问单例实例(可能想要更改该名称),无需导入标题的任何文件(您必须执行此操作)。您必须在程序的早期某处调用单例设置方法(defaultInstance或其他),例如+instance,以确保在使用指针之前设置指针。

  
      
  • 我所描述的是一种合理的方法吗?
  •   

我认为还有其他更好的方法,如上所述和Paul.s的答案。

  
      
  • 声明属性-applicationDidFinishLaunching
  • 是否正确   

是的,具有此指针的类不需要拥有它,因为单例拥有自己;

  
      
  • 我所描述的是否有任何性能问题?实际上直接调用实例会更好吗?
  •   

无论哪种方式,weak[Constants instance]您都在发送消息。你第一次做self.constants时,你做了两次。然而,这些都不应该是一个真正令人担忧的问题。

  
      
  • 考虑一种情况,你有20个类,每个类都需要它自己指向self.constants实例的指针。这种方法会起作用吗?
  •   

对我来说,这看起来很笨拙而且不够优雅。