最近,在使用Objective-C和其中编写的各种库时,我注意到了两种非常流行的单例模式.一个版本获取单例实例并调用其实例方法,而另一个版本只公开类方法,从不提供可使用的实例.它们的目的都是抽象访问单个资源(StoreKit、CoreData、Parse API等).例如,以下是MKStoreKit中使用的前一种方法:

// initialize singleton during app boot
[MKStoreManager sharedManager]

// sometime later in the app
[[MKStoreManager sharedManager] buyFeature:kFeatureAId 
                                onComplete:^(NSString* purchasedFeature)
 {
     NSLog(@"Purchased: %@", purchasedFeature);
 }
                               onCancelled:^
 {
     NSLog(@"User Cancelled Transaction");
 }];

或者,应用程序默认值等..另一种方法可以在MagicalRecord或这里的Parse API中看到:

// configure API credentials sometime during app boot
[Parse setApplicationId:@"123456"
              clientKey:@"123456"];

// sometime later
PFObject *testObject = [PFObject objectWithClassName:@"TestObject"];
[testObject setObject:@"bar" forKey:@"foo"];
[testObject save];

这两种方法的优缺点是什么?其中一种方法从根本上优于另一种方法吗?

不必检索共享实例可以节省一些屏幕空间(性能差异可能无关紧要),但我是否在其他方面搞砸了自己,例如,可测试性方面?

谢谢

推荐答案

基于类方法有两种不同的实现方法:

  • 使用一个对所有人都隐藏的类创建一个单例实例,并将其方法隐藏在具有相同签名的包装类方法后面,或者
  • 制作完成所有工作的类方法

第一个实现的含义是,你可以用一个单例做任何事情,你可以用隐藏的单例做任何事情:

  • 使用子类成为可能
  • 在运行中间切换实例很容易.
  • 状态存在于实例变量中
  • 初始化遵循熟悉的模式

如果您 Select 不使用单例的实现,那么您将依赖静态变量来保持当前状态.这是一个合法的 Select ,但是初始化模式变得不同(也许甚至使用dispatch_once),您不能在中间切换实现,而不依赖于一些丑陋的if个条件,并且使用子类变得更加棘手.

测试第一个实现比测试第二个实现要容易一些,因为您可以为测试提供单独的单例实现,可能是通过后门;在基于静态的实现中,不能采用这种方法.

总而言之,我将使用基于单例的解决方案,单例可以 Select 隐藏在"facade"后面,提供对单例方法的访问.我不会使用所有状态都必须放在静态变量中的实现.

Objective-c相关问答推荐

try 从 id 确定类的类型时,Objective-C消息传递不合格的 id

如何在 NSImage CIFilter ObjC 周围创建边框

iOS中的非延迟图像加载

CABasicAnimation 无 HUGE_VALF 无限重复?

观察 UIDatePicker 的变化

更改 UIBarButtonItem 的 Tint colored颜色

UILabel 的角半径属性在 iOS 7.1 中不起作用

如何将 .plist 文件中的数据 struct 读入 NSArray

如何编写 OS X Finder 插件

为什么 NSOrderedSet 不继承自 NSSet?

将 HTTP 标头添加到 NSURLRequest

'supportedInterfaceOrientations' 实现中的返回类型冲突: - 警告

Objective-C 中的属性和实例变量

iOS 11 large-title导航栏不折叠

100% 不透明度 UILabel 超过 50% 不透明度背景(UIView?)

选中时选中的 UItableViewCell 保持蓝色

字符串常量和字符串文字有什么区别?

将数据传回前一个视图控制器

将浮点数四舍五入到objective C中的下一个整数?

如何设置字体大小以填充 UILabel 高度?