我如何处置自己在Objective-C中的股份?

我如何处置自己在Objective-C中的股份?,objective-c,cocoa,Objective C,Cocoa,如果有一个类本身具有sharedInstance单例模式或另一个类的共享实例,那么如何确保在程序退出时正确释放共享实例?更好的是,你能给我指一些关于这个的文档吗 为清晰起见,删除了所有其他方法的示例类: @interface Foo : NSObject { } + (Foo*)sharedInstance; @end .m文件: static Foo* SharedInstance; @implementation Foo + (Foo*)sharedInstance { if

如果有一个类本身具有sharedInstance单例模式或另一个类的共享实例,那么如何确保在程序退出时正确释放共享实例?更好的是,你能给我指一些关于这个的文档吗

为清晰起见,删除了所有其他方法的示例类:

@interface Foo : NSObject {
}
+ (Foo*)sharedInstance;

@end
.m文件:

static Foo* SharedInstance;

@implementation Foo

+ (Foo*)sharedInstance
{
    if (!SharedInstance)
        SharedInstance = [[Foo alloc] init]; // possible memory leak?

    return SharedInstance;
}
@end

在上面的代码中,我什么时候可以释放SharedInstance?

除非共享实例之外还有需要释放的资源,例如文件、清理时的通知等,否则您可以在应用程序退出时清理SharedInstance的内存。即使是文件和网络套接字等也会在应用程序退出时由操作系统清理,因此您也可以不清理它们


如果在应用程序退出之前确实需要执行清理操作,则必须向共享实例添加清理或类似方法,并添加静态方法来释放共享实例。

除非共享实例之外还有需要释放的资源,例如文件、清理时的通知等。,您只需在应用程序退出时清除sharedInstance的内存即可。即使是文件和网络套接字等也会在应用程序退出时由操作系统清理,因此您也可以不清理它们


如果您确实需要在应用程序退出之前执行清理操作,则必须向共享实例添加清理或类似的方法,并添加静态方法来释放共享实例。

正如Barry指出的,通常不需要在退出时清理任何东西,但您可以做的是设置一个实现

- (void)applicationWillTerminate:(NSNotification *)aNotification
然后在应用程序即将退出之前调用此方法。在这个方法中,您可以调用共享实例类的一些静态方法来清理内部缓存的共享实例


然而,不存在应用程序退出之后的内存泄漏之类的情况。如果您的应用程序终止,它所拥有的所有内存都将返回给系统,无论它是如何分配的。如果情况并非如此,并且您的应用程序将崩溃,那么在崩溃之前使用的内存最终将丢失给系统,这是不可接受的。在多任务操作系统上,崩溃的应用程序不得对系统的其余部分产生任何负面影响

通常没有必要像Barry指出的那样在退出时清理任何东西,但您可以做的是设置一个实现

- (void)applicationWillTerminate:(NSNotification *)aNotification
然后在应用程序即将退出之前调用此方法。在这个方法中,您可以调用共享实例类的一些静态方法来清理内部缓存的共享实例


然而,不存在应用程序退出之后的内存泄漏之类的情况。如果您的应用程序终止,它所拥有的所有内存都将返回给系统,无论它是如何分配的。如果情况并非如此,并且您的应用程序将崩溃,那么在崩溃之前使用的内存最终将丢失给系统,这是不可接受的。在多任务操作系统上,崩溃的应用程序不得对系统的其余部分产生任何负面影响

这样做比较好

+ (Foo*)sharedInstance
{
    if (!SharedInstance)
        SharedInstance = [[[Foo alloc] init] autorelease];

    return SharedInstance;
}
@end

使用共享实例的类B可以保留和释放它

这样做比较好

+ (Foo*)sharedInstance
{
    if (!SharedInstance)
        SharedInstance = [[[Foo alloc] init] autorelease];

    return SharedInstance;
}
@end

使用共享实例的类B可以保留和释放它

无论你做什么,都不要自动释放一个未保留的共享实例,因为它将是免费的,你会被搞砸的。按您当前的方式执行,但在applicationWillTerminate中:放置如下内容:

BackgroundFactory * factory = [self sharedFactory];
// prevent an analyzer annoyance
NSValue * value = [NSValue valueWithPointer:factory];
id fac = (id)[value pointerValue];
[fac release];

请注意,sharedFactory是返回共享实例的方法。所有这些代码都应该放在+freeSharedInstance方法中。

无论你做什么,都不要自动释放一个未保留的共享实例,因为它将是免费的,你会被搞砸。按您当前的方式执行,但在applicationWillTerminate中:放置如下内容:

BackgroundFactory * factory = [self sharedFactory];
// prevent an analyzer annoyance
NSValue * value = [NSValue valueWithPointer:factory];
id fac = (id)[value pointerValue];
[fac release];

请注意,sharedFactory是返回共享实例的方法。所有这些代码都应该放在+freeSharedInstance方法中。

对于单例,我不担心这一点,但请记住,即使没有必要,释放对象仍然是一种很好的做法。如果你重构代码,使内存管理成为一个问题,它会使事情保持正常。是的,但是你仍然不会在类中释放单例引用。你要做的是获得一个单例的ref,并将其视为非单例,例如保留它,然后再释放它,但是ref计数永远不会达到零,因此单例不会消失,即使在释放后也不会消失。我不会为单例担心,但是请记住,即使不需要释放对象,释放对象仍然是一种好的做法。如果你重构了代码,那么内存管理就会成为一个问题,这会使事情保持正常 'd仍然没有在类中发布单例引用。你要做的是获得一个单例的ref,并将其视为非单例,例如保留它,然后再释放它,但是ref计数永远不会达到零,因此单例不会消失,即使在释放后也不会消失。