我刚开始编写单例,我必须使用一个用于当前的iOS项目。其中一个要求是它可以被杀死。我知道这违背了单身人士的设计,但这是应该/可以做的事情吗?
答案 0 :(得分:8)
当然可以完成,但是如果你正在寻找一个可以创建的对象,然后在不需要的时候释放...这听起来像一个普通的对象。 :)
一般来说,单身人士控制自己的生命周期。你将在这里进行单方面的讨论,除非你更多地谈到这两个要求(一个,你使用单身,两个,它可以随意发布),以及为什么它们在你的情况下都有意义。
这可能是因为单例包装了一些本质上唯一的其他资源(如文件资源或网络连接)。如果这是真的,那么通常单例是该资源的“管理者”,并且您将通过单例的接口公开对该资源的控制。
或者可能是因为单例对象持有大量内存(某种缓冲区),并且您希望确保在必要时刷新。如果是这种情况,那么你可以更聪明地创建和释放内存的每个方法,或者你可以让单身人员监听低内存系统通知并且表现得恰当。
基本上,我很难构建一个案例,它确实释放了单例对象本身。一个基本对象在内存中只占用少量字节,并且不会因为闲逛而伤害任何人。
答案 1 :(得分:6)
我知道这违反了单身人士的设计
它也违反了Objective-C中通常的内存管理模式。通常,对象会保留另一个对象以防止它被破坏,并释放它以允许对象被销毁。但是,明确地破坏对象并不是其他对象可以做的事情。
考虑如果对象A获得单例类S的共享实例S1会发生什么。如果A保留S1,即使某个类方法释放S并将指向共享实例的全局变量设置为S,S1也将继续存在零。当类稍后创建一个新的共享实例S2时,将有两个S实例,即S1和S2。这违反了首先定义单例的属性。
您可以通过覆盖-retain
并且可能调整-release
来解决此问题,但这似乎很难解决首先不应存在的问题。
一种可能的替代方法是重置您的共享对象,而不是试图销毁它。如果需要,可以将其所有属性设置为某个已知(可能无效)状态,然后使用类方法重新初始化共享对象。请注意所有这些对可能使用共享对象的任何对象的影响。
答案 2 :(得分:6)
几乎我写过的每一个单身(除了完全以UI为中心的控制器)最终被重构为不是单身人士。每一个。单。之一。
因此,我已经停止写单身。我编写的类在实例中维护状态,就像任何普通的类一样,并且与其他实例隔离开来。如果通知很重,他们总是将self
作为通知对象传递。他们有代表。他们保持内部状态。他们避免在真正的全球状态之外的全球化。
而且,通常,我的应用程序中可能只有一个所述类的实例。这个实例就像一个单例,事实上,我甚至可以创建一种方便的方法来获取它,可能是通过App的委托或通过类方法(有时甚至可能被命名为sharedInstance
)。
所述类包括通常分为两部分的拆除代码;用于以后恢复当前状态的代码和用于释放实例相关资源的代码。
像单身人士一样方便。准备好在需要时进行多重实例化。
答案 3 :(得分:3)
当然没问题。您提供了一个新的类方法:[MyClass killSingleton];该方法释放单例并将其内部引用设置为nil。下次有人询问[MyClass sharedSingleton]时,您将执行与创建之前相同的步骤。
编辑:实际上,在过去,这样的例程可能会覆盖release
选择器,并拒绝离开。因此,正如下面的第一条评论所述,这是一个具有静态范围的对象 - 它通过静态变量保持活动状态,保持对象的保留计数为1。然而,通过添加一个新的类方法来nil out ivar(在ARC下),从而释放它,实现了期望的结果。实例化和释放静态对象的控制完全通过类方法完成,因此易于维护和调试。
答案 4 :(得分:1)
这违反了Singleton的概念,但它可以通过以下方式实现基于ARC的项目
//ARC
@interface Singleton : NSObject
+ (Singleton *)sharedInstance;
+ (void)selfDestruct;
@end
@implementation Singleton
static Singleton *sharedInstance = nil;
+ (Singleton *)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[Singleton alloc] init];
}
return sharedInstance;
}
+ (void) selfDestruct {
sharedInstance = nil;
}
@end
答案 5 :(得分:0)
//This can be implemented using bool variable. If bool no create new instance.
@interface Singleton : NSObject
+ (Singleton *)sharedInstance;
@end
@implementation Singleton
static Singleton *sharedInstance = nil;
+ (Singleton *)sharedInstance {
if (!keepInstance) {
sharedInstance = [[Singleton alloc] init];
keepInstance = YES;
}
return sharedInstance;
}
@end
答案 6 :(得分:0)
我需要清除单身人士,所以我最终做了以下事情:
- (void)deleteSingleton{
@synchronized(self) {
if (sharedConfigSingletone != nil) {
sharedConfigSingletone = nil;
}
}
}
希望它有所帮助。