完全释放Objective-C单例

时间:2012-08-14 02:09:26

标签: cocoa-touch design-patterns singleton

我刚开始编写单例,我必须使用一个用于当前的iOS项目。其中一个要求是它可以被杀死。我知道这违背了单身人士的设计,但这是应该/可以做的事情吗?

7 个答案:

答案 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;
    }
}
}

希望它有所帮助。