使用 [NSObject load] 初始化没有自动释放池的系统

Posted

技术标签:

【中文标题】使用 [NSObject load] 初始化没有自动释放池的系统【英文标题】:Using [NSObject load] to initialized system with no autorelease pool 【发布时间】:2012-04-29 00:54:42 【问题描述】:

我正在使用 Xcode 4.3.2 和 ios 模拟器编写一个 iPad 应用程序。我有一系列类,我想在启动时向单例注册,以便其他类可以通过这些注册的类提供的单例请求服务。

为了实现这种行为,我一直依赖于重写 NSObject 上的 load 类方法。但是,我发现所有由 load 方法执行的代码都发生在 main 函数之外,然后才有机会设置自动释放池。我在我的应用程序中使用了一些当前禁止使用或自动引用计数的第 3 方技术,因此我需要依靠自动释放池来帮助管理已创建对象的生命周期。

在注册过程中,模拟器的调试控制台中出现了许多消息,抱怨在没有自动释放池的情况下调用了自动释放。其中之一与单例分配的字典有关。其他与从堆栈复制并存储在该单例字典中的块对象有关。

我不清楚这些调试消息有多严重。我怀疑字典的分配可能没有问题,因为单例应该存在于应用程序的整个生命周期中,并且该字典可能永远不会被释放。同样,存储在字典中的块也应该保留,所以我想知道在调用 copy 方法后是否不需要对它们调用 autorelease。

或者也许有另一种方法来完成我想要的,而不必求助于可能不太成问题的当前技术

人们可以就这个问题提出什么建议?

【问题讨论】:

【参考方案1】:

你应该有更好的运气覆盖+[NSObject initialize] 而不是loadinitialize 在第一次引用类时调用,而不是在加载类所在的图像时调用。这将使您更好地处理这一切。

【讨论】:

我认为这对我的目的不起作用。我希望对象自动将自己注册到单例中。没有任何东西会引用该对象来调用初始化方法。无论对象是否已被使用,都会调用 load 方法。 然后在加载方法中设置自己的池【参考方案2】:

一个好的方法是使用dispatch_once_t,它在每个运行时只在所有线程中执行一次:

+ (id)sharedInstance

    static dispatch_once_t once;
    static SingletonClass *sharedInstance;
    dispatch_once(&once, ^  sharedInstance = [[self alloc] init]; );
    return sharedInstance;

【讨论】:

也许我没有正确地遵循事情。如果我理解上面的代码,它似乎是为了帮助实施单例模式。我已经有了解决方案,尽管上面的代码看起来更简单。我关心的不是强制执行单例。问题是,当第一次需要单例时,没有可用的自动释放池,因为对象试图通过使用 +load 方法自动向它注册,该方法在主函数执行之前调用每个类。

以上是关于使用 [NSObject load] 初始化没有自动释放池的系统的主要内容,如果未能解决你的问题,请参考以下文章

NSObject的load和initialize方法

NSObject 用 nib 加载 UIView 但文件所有者是 UIViewController

UICollectionViewDelegate 没有在具有自定义 UICollectionViewCell 和 NSObject 控制器的 UICollectionView 子类上触发

强制 Nib loader 使用 init?(with:) for custom subclass of NSObject in iOS

swift学习第十三天:类的构造函数

NSObject