Mar*_*ark 12 iphone variables static memory-management objective-c
我有一个静态方法,它创建一个类的实例并将其放在静态变量中.我想知道在这种情况下,内存管理的正确方法是什么.
你不能把它放在dealloc方法中,因为虽然它可以访问静态变量,但任何创建的实例方法都会释放getInstance.
我想可能有一个创建静态破坏方法的选项,它将手动释放内存,并且可以由appWillTerminate用户调用,但这看起来有点奇怪.
那么,问题是: 释放静态变量的正确方法是什么?
// MyClass.m
#import "MyClass.h"
static MyClass *myClass; // How to properly do memory management
@implementation MyClass
+ (MyClass *)sharedMyClass {
if (myClass == nil) myClass = [[MyClass alloc] init];
return myClass;
}
@end
Run Code Online (Sandbox Code Playgroud)
您可以不释放它们,这很好,因为应用程序无论如何都要关闭.iPhone上的Cocoa已经这样做了,它并没有完全删除所有内容,只是让应用程序被吹走了.
或者您可以从appWillTerminate或其他一些关闭功能中删除它.
您需要查看iPhone开发中心的"创建单例",了解如何正确实现该模式.你不会释放你的单身,只是在应用程序退出时让它死掉.
此外,如果您是多线程的,您可能希望将该alloc包装在@synchronize(self){}中
这是全文:
某些类的Foundation和Application Kit创建单例对象.在"严格"实现中,单例是当前进程中类的唯一允许实例.但是您也可以使用更灵活的单例实现,其中工厂方法始终返回相同的实例,但您可以分配和初始化其他实例.NSFileManager类适合后一种模式,而UIApplication适合前者.当您要求UIApplication的实例时,它会向您传递对唯一实例的引用,如果它尚不存在则分配并初始化它.
单例对象充当一种控制中心,指导或协调该类的服务.当概念上只有一个实例时(例如,NSWorkspace),您的类应该生成单例实例而不是多个实例.当可以想象某天可能存在多个实例时,可以使用单例实例而不是工厂方法或函数.
要在当前进程中创建单例作为类的唯一允许实例,您需要具有类似于清单2-15的实现.此代码执行以下操作:
声明单个对象的静态实例并将其初始化为nil.在类的类工厂方法(命名为"sharedInstance"或"sharedManager")中,生成类的实例,但仅当静态实例为nil时.如果有人试图直接分配和初始化类的实例而不是使用类工厂方法,则覆盖allocWithZone:方法以确保未分配另一个实例.相反,只需返回共享对象.实现基本协议方法copyWithZone:,release,retain,retainCount和autorelease来做相应的事情以确保单例状态.(这些方法的最后四个适用于内存管理代码,而不是垃圾收集代码.)清单2-15严格实现单例静态MyGizmoClass
*sharedGizmoManager = nil;
+ (MyGizmoClass*)sharedManager {
if (sharedGizmoManager == nil) {
sharedGizmoManager = [[super allocWithZone:NULL] init];
}
return sharedGizmoManager; }
+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedManager] retain]; }
- (id)copyWithZone:(NSZone *)zone {
return self; }
- (id)retain {
return self; }
- (NSUInteger)retainCount {
return NSUIntegerMax; //denotes an object that cannot be released }
- (void)release {
//do nothing }
- (id)autorelease {
return self; }
Run Code Online (Sandbox Code Playgroud)
如果您需要单例实例(由类工厂方法创建和控制),但也能够通过分配和初始化根据需要创建其他实例,请不要覆盖allocWithZone:以及其后的其他方法,如清单2-15所示.
更新:现在有一种更简单的方法来创建单身人士
+ (MyClass*)sharedInstance
{
static MyClass* _sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[MyClass alloc] init];
});
return _sharedInstance;
}
Run Code Online (Sandbox Code Playgroud)
使用这种新样式,您无需担心@syncronize或重写内存管理方法.