Cocoa touch 完全解除分配Objective-C单例

Cocoa touch 完全解除分配Objective-C单例,cocoa-touch,design-patterns,singleton,Cocoa Touch,Design Patterns,Singleton,我刚开始编写单例,我必须在当前的iOS项目中使用单例。其中一个要求是它可以被杀死。我知道这违背了单例的设计,但这是应该/可以做到的吗?当然可以做到,但是如果你正在寻找一个可以创建的对象,然后在不需要时发布。。。听起来像是一个普通的物体。:) 一般来说,单身者控制着自己的生命周期。在这里,您将得到片面的讨论,除非您更多地说明这两个要求(一个是您使用单例,另一个是它可以随意发布),以及为什么它们在您的案例中都有意义 这可能是因为单例封装了其他一些固有唯一的资源(如文件资源或网络连接)。如果这是真的

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

当然可以做到,但是如果你正在寻找一个可以创建的对象,然后在不需要时发布。。。听起来像是一个普通的物体。:)


一般来说,单身者控制着自己的生命周期。在这里,您将得到片面的讨论,除非您更多地说明这两个要求(一个是您使用单例,另一个是它可以随意发布),以及为什么它们在您的案例中都有意义

这可能是因为单例封装了其他一些固有唯一的资源(如文件资源或网络连接)。如果这是真的,那么单例通常是该资源的“管理器”,您可以通过单例接口公开对该资源的控制

或者可能是因为singleton对象保留了一吨内存(某种类型的缓冲区),您希望确保在必要时刷新它。如果是这种情况,那么您可以更明智地使用它的每一种方法,根据需要创建和释放内存,或者让单例侦听内存不足的系统通知,并采取适当的行为


从本质上讲,我很难构建一个案例,在这个案例中,释放singleton对象本身是有意义的。一个基本对象只占用内存中的一小部分字节,并且不会因为闲逛而伤害任何人。

当然没问题。您提供了一个新的类方法:[MyClass killSingleton];该方法释放singleton并将其内部引用设置为nil。下次有人问[MyClass sharedSingleton]时,您将按照之前的步骤创建它

编辑:实际上,在过去,这样的例行程序可能会覆盖
发布
选择器,并拒绝离开。因此,正如下面的第一条注释所述,这是一个具有静态作用域的对象—它通过一个静态变量保持活动状态,在对象上保持retain计数为1。然而,通过添加一个新的类方法来消除ivar(在ARC下),从而释放它,实现了期望的结果。对实例化和释放静态对象的控制完全通过类方法完成,因此易于维护和调试

我知道这违背了单身汉的设计

这也违背了Objective-C中通常的内存管理模式。通常,一个对象会保留另一个对象以防止其被破坏,并释放它以允许该对象被破坏。但是,显式销毁一个对象并不是其他对象可以做的事情

考虑如果对象A获得单例类S的共享实例S1会发生什么。如果A保留S1,则S1将继续存在,即使某些类方法释放S并将指向共享实例的全局变量设置为nil。当类稍后创建一个新的共享实例S2时,将有两个S的实例,即S1和S2。这违反了首先定义单例的属性

您可以通过覆盖
-retain
和可能的swizzling
-release
来绕过这个问题,但是解决一个本来不应该存在的问题似乎有很多复杂性


一种可能的替代方法是重置共享对象,而不是尝试销毁它。如果需要,可以将它的所有属性设置为某些已知(可能无效)状态,然后使用类方法重新初始化共享对象。请注意这一切对可能使用共享对象的任何对象的影响。

我所写的几乎每一个单例(完全以用户界面为中心的控制器除外)最终都会被重构为非单例。每一个单身。一个

因此,我不再写单身汉了。我像任何普通类一样,编写在实例中维护状态的类,并与其他实例隔离。如果它们的通知量很大,它们总是将
self
作为通知对象传递。他们有代表。它们保持内部状态。他们避开真正全球化国家之外的全球化国家

而且,通常,在我的应用程序中可能正好有一个上述类的实例。一个实例的行为就像一个单例,事实上,我甚至可能创建一种方便的方法来获取它,可能通过应用程序的委托或类方法(有时甚至可能被命名为
sharedInstance

所述类包括通常分为两部分的分解代码;保存当前状态以供以后恢复的代码,以及释放实例关联资源的代码


像单身汉一样方便。准备在需要时进行多次实例化。

这不符合单例的概念,但对于基于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

我需要清除单身汉,因此我最终做了以下工作:

- (void)deleteSingleton{
@synchronized(self) {
    if (sharedConfigSingletone != nil) {
        sharedConfigSingletone = nil;
    }
}
}

希望这能有所帮助。

根据定义,单身人士永远无法再次分配,因此,解除分配的概念没有任何意义。为终止合同而拆除?当然但无论如何,你不能指望这种情况发生。@bbum这取决于定义。对我来说,明确的定义来自经典的GoF书籍:“确保一个类只有一个实例”。这并不排除销毁和重建。根据Cocoa和iOS开发中的定义,@bbum您指的是一些文档还是其他常见的定义?我只是好奇,因为对我来说,Cocoa中的单例总是Cocoa基础指南中的一个有问题的部分(该指南模拟了重新计数等)。在操作系统内和跨第三方代码库(包括文档)的单例实现超过20年的惯例
- (void)deleteSingleton{
@synchronized(self) {
    if (sharedConfigSingletone != nil) {
        sharedConfigSingletone = nil;
    }
}
}