Objective-C / iPhone内存管理静态变量

时间:2022-09-07 20:09:25

I have a static method that creates an instance of the class and puts it in the static variable. I am wondering what the proper way of memory management is in this situation.

我有一个静态方法,它创建类的实例并将其放在静态变量中。我想知道在这种情况下,内存管理的正确方法是什么。

You can't put it in the dealloc-method, because although it can access the static variable any instance method that is created that get's released will also release the sharedInstance.

你不能把它放在dealloc方法中,因为虽然它可以访问静态变量,但任何创建的实例方法都会释放getInstance。

I guess there might be an option of creating a static destroy method which will manualy release the memory and can be called by the user from appWillTerminate, but that seems a bit odd.

我猜可能有一个选项可以创建一个静态破坏方法,该方法将手动释放内存,并且可以由appWillTerminate用户调用,但这看起来有点奇怪。

So, again, the question: What is the proper way of releasing a static variable?

那么,问题是:释放静态变量的正确方法是什么?


// 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

3 个解决方案

#1


8  

You can either not release them, which is fine since the app is shutting down anyway. Cocoa on the iPhone already does this, it doesn't completely delete everything, it just lets the app get blown away.

您可以不释放它们,这很好,因为应用程序正在关闭。 iPhone上的Cocoa已经做到了这一点,它没有完全删除所有内容,只是让应用程序被吹走了。

Or you can delete it from appWillTerminate or some other shutdown function.

或者您可以从appWillTerminate或其他一些关闭功能中删除它。

#2


7  

You'll want to have a look at "Creating a Singleton" on the iPhone dev center to see how to properly implement that pattern. You won't be releasing your singleton, just letting it die when the application exits.

您需要查看iPhone开发中心的“创建单例”,了解如何正确实现该模式。你不会释放你的单身,只是在应用程序退出时让它死掉。

Also, if you're multithreaded you'll probably want to wrap that alloc in a @synchronize( self ) {}

此外,如果您是多线程的,您可能希望将该alloc包装在@synchronize(self){}中

Here is the full text:

这是全文:

Some classes of Foundation and the Application Kit create singleton objects. In a “strict” implementation, a singleton is the sole allowable instance of a class in the current process. But you can also have a more flexible singleton implementation in which a factory method always returns the same instance, but you can allocate and initialize additional instances.The NSFileManager class fits this latter pattern, whereas the UIApplication fits the former. When you ask for an instance of UIApplication, it passes you a reference to the sole instance, allocating and initializing it if it doesn’t yet exist.

某些类的Foundation和Application Kit会创建单个对象。在“严格”实现中,单例是当前进程中类的唯一允许实例。但是您也可以使用更灵活的单例实现,其中工厂方法始终返回相同的实例,但您可以分配和初始化其他实例.NSFileManager类适合后一种模式,而UIApplication适合前者。当您请求UIApplication的实例时,它会向您传递对唯一实例的引用,如果它尚不存在则分配并初始化它。

A singleton object acts as a kind of control center, directing or coordinating the services of the class. Your class should generate a singleton instance rather than multiple instances when there is conceptually only one instance (as with, for example, NSWorkspace). You use singleton instances rather than factory methods or functions when it is conceivable that there might be multiple instances one day.

单例对象充当一种控制中心,指导或协调该类的服务。当概念上只有一个实例时(例如,NSWorkspace),您的类应该生成单例实例而不是多个实例。当可以想象某天可能有多个实例时,您可以使用单例实例而不是工厂方法或函数。

To create a singleton as the sole allowable instance of a class in the current process, you need to have an implementation similar to Listing 2-15. This code does the following:

要在当前进程中创建单例作为类的唯一允许实例,您需要具有类似于清单2-15的实现。此代码执行以下操作:

Declare a static instance of your singleton object and initialize it to nil. In your class factory method for the class (named something like “sharedInstance” or “sharedManager”), generate an instance of the class but only if the static instance is nil. Override the allocWithZone: method to ensure that another instance is not allocated if someone tries to allocate and initialize an instance of your class directly instead of using the class factory method. Instead, just return the shared object. Implement the base protocol methods copyWithZone:, release, retain, retainCount, and autorelease to do the appropriate things to ensure singleton status. (The last four of these methods apply to memory-managed code, not to garbage-collected code.) Listing 2-15 Strict implementation of a singleton static MyGizmoClass

声明单个对象的静态实例并将其初始化为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; }

If you want a singleton instance (created and controlled by the class factory method) but also have the ability to create other instances as needed through allocation and initialization, do not override allocWithZone: and the other methods following it as shown in Listing 2-15.

如果你想要一个单例实例(由类工厂方法创建和控制),但也能够通过分配和初始化根据需要创建其他实例,不要覆盖allocWithZone:和其后的其他方法,如清单2-15所示。


UPDATE: There is now a much easier way to create a singleton

更新:现在有一种更简单的方法来创建单身人士

+ (MyClass*)sharedInstance
{
  static MyClass* _sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    _sharedInstance = [[MyClass alloc] init];
  });

  return _sharedInstance;
}

Using this new style you don't need to worry about the @syncronize or overriding the memory management methods.

使用这种新样式,您无需担心@syncronize或覆盖内存管理方法。

#3


1  

static variable or class remains in memory Untill lifetime of your application

静态变量或类保留在内存中直到应用程序的生命周期

So if it is UnUsed then make

因此,如果它是UnUsed,那么make

Your_variable = nil;

while declaring use static _datatype variable = nil; which help while initializing .. and memory management

同时声明使用static _datatype variable = nil;这有助于初始化..和内存管理

///**************************
// MyClass.m
#import "MyClass.h"

static MyClass *myClass = nil;

@implementation MyClass

+ (MyClass *)sharedMyClass {
    if (myClass == nil)
            myClass = [[MyClass alloc] init];
    return myClass;
}

@end

#1


8  

You can either not release them, which is fine since the app is shutting down anyway. Cocoa on the iPhone already does this, it doesn't completely delete everything, it just lets the app get blown away.

您可以不释放它们,这很好,因为应用程序正在关闭。 iPhone上的Cocoa已经做到了这一点,它没有完全删除所有内容,只是让应用程序被吹走了。

Or you can delete it from appWillTerminate or some other shutdown function.

或者您可以从appWillTerminate或其他一些关闭功能中删除它。

#2


7  

You'll want to have a look at "Creating a Singleton" on the iPhone dev center to see how to properly implement that pattern. You won't be releasing your singleton, just letting it die when the application exits.

您需要查看iPhone开发中心的“创建单例”,了解如何正确实现该模式。你不会释放你的单身,只是在应用程序退出时让它死掉。

Also, if you're multithreaded you'll probably want to wrap that alloc in a @synchronize( self ) {}

此外,如果您是多线程的,您可能希望将该alloc包装在@synchronize(self){}中

Here is the full text:

这是全文:

Some classes of Foundation and the Application Kit create singleton objects. In a “strict” implementation, a singleton is the sole allowable instance of a class in the current process. But you can also have a more flexible singleton implementation in which a factory method always returns the same instance, but you can allocate and initialize additional instances.The NSFileManager class fits this latter pattern, whereas the UIApplication fits the former. When you ask for an instance of UIApplication, it passes you a reference to the sole instance, allocating and initializing it if it doesn’t yet exist.

某些类的Foundation和Application Kit会创建单个对象。在“严格”实现中,单例是当前进程中类的唯一允许实例。但是您也可以使用更灵活的单例实现,其中工厂方法始终返回相同的实例,但您可以分配和初始化其他实例.NSFileManager类适合后一种模式,而UIApplication适合前者。当您请求UIApplication的实例时,它会向您传递对唯一实例的引用,如果它尚不存在则分配并初始化它。

A singleton object acts as a kind of control center, directing or coordinating the services of the class. Your class should generate a singleton instance rather than multiple instances when there is conceptually only one instance (as with, for example, NSWorkspace). You use singleton instances rather than factory methods or functions when it is conceivable that there might be multiple instances one day.

单例对象充当一种控制中心,指导或协调该类的服务。当概念上只有一个实例时(例如,NSWorkspace),您的类应该生成单例实例而不是多个实例。当可以想象某天可能有多个实例时,您可以使用单例实例而不是工厂方法或函数。

To create a singleton as the sole allowable instance of a class in the current process, you need to have an implementation similar to Listing 2-15. This code does the following:

要在当前进程中创建单例作为类的唯一允许实例,您需要具有类似于清单2-15的实现。此代码执行以下操作:

Declare a static instance of your singleton object and initialize it to nil. In your class factory method for the class (named something like “sharedInstance” or “sharedManager”), generate an instance of the class but only if the static instance is nil. Override the allocWithZone: method to ensure that another instance is not allocated if someone tries to allocate and initialize an instance of your class directly instead of using the class factory method. Instead, just return the shared object. Implement the base protocol methods copyWithZone:, release, retain, retainCount, and autorelease to do the appropriate things to ensure singleton status. (The last four of these methods apply to memory-managed code, not to garbage-collected code.) Listing 2-15 Strict implementation of a singleton static MyGizmoClass

声明单个对象的静态实例并将其初始化为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; }

If you want a singleton instance (created and controlled by the class factory method) but also have the ability to create other instances as needed through allocation and initialization, do not override allocWithZone: and the other methods following it as shown in Listing 2-15.

如果你想要一个单例实例(由类工厂方法创建和控制),但也能够通过分配和初始化根据需要创建其他实例,不要覆盖allocWithZone:和其后的其他方法,如清单2-15所示。


UPDATE: There is now a much easier way to create a singleton

更新:现在有一种更简单的方法来创建单身人士

+ (MyClass*)sharedInstance
{
  static MyClass* _sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    _sharedInstance = [[MyClass alloc] init];
  });

  return _sharedInstance;
}

Using this new style you don't need to worry about the @syncronize or overriding the memory management methods.

使用这种新样式,您无需担心@syncronize或覆盖内存管理方法。

#3


1  

static variable or class remains in memory Untill lifetime of your application

静态变量或类保留在内存中直到应用程序的生命周期

So if it is UnUsed then make

因此,如果它是UnUsed,那么make

Your_variable = nil;

while declaring use static _datatype variable = nil; which help while initializing .. and memory management

同时声明使用static _datatype variable = nil;这有助于初始化..和内存管理

///**************************
// MyClass.m
#import "MyClass.h"

static MyClass *myClass = nil;

@implementation MyClass

+ (MyClass *)sharedMyClass {
    if (myClass == nil)
            myClass = [[MyClass alloc] init];
    return myClass;
}

@end