0

我想知道你将如何释放一个单例

+ (DSActivityView *)activityViewForView:(UIView *)addToView withLabel:(NSString *)labelText width:(NSUInteger)labelWidth;
 {
    // Not autoreleased, as it is basically a singleton:
    return [[self alloc] initForView:addToView withLabel:labelText width:labelWidth];
 }

使用分析工具对此进行分析时,我收到以下错误:第 90 行对象的潜在泄漏。这是返回的行。

我已经尝试过解决错误消息问题的自动释放,但我不相信它是正确的解决方案,因为我读到自动释放单例并不好。有人可以帮助我确定如何最好地释放这个对象吗?

谢谢

4

3 回答 3

2

分析器向您发出警告的原因基本上是方法名称:

+ (DSActivityView *)activityViewForView:(UIView *)addToView withLabel:(NSString *)labelText width:(NSUInteger)labelWidth;

根据 Objective-C 约定,所有以 "create"/"new"/... 开头的方法名称都返回一个保留对象;您的方法属于便利构造函数的类别,这些构造函数预计会返回自动释放的对象,因此会发出警告。

另一方面,你说这是一个单例,但实际上不是。因此,您最终可能会多次调用此方法,从而导致实际泄漏。使您的方法更安全(并且更像单例)的基本方法是:

+ (DSActivityView *)activityViewForView:(UIView *)addToView withLabel:(NSString *)labelText width:(NSUInteger)labelWidth;
{
    static DSActivityView* gDSActivityViewSingleton = nil;
    if (!gDSActivityViewSingleton)
          gDSActivityViewSingleton = [[self alloc] initForView:addToView withLabel:labelText width:labelWidth];
    return gDSActivityViewSingleton;
}

这既可以使分析仪放松,又可以让您在方法误用的可能性面前更加安全。

于 2012-09-03T16:04:53.520 回答
1

使用自动释放。没有理由不这样做。基本上,对象的所有权属于对象,因此您永远无法手动释放它。作为一个单例,如果您不拥有它并不重要,因为大概下次您调用它并在范围内需要它时,您将使用另一种方便的方法,它将再次被实例化。

如果您想拥有该对象的所有权,那么您需要照常实例化它,然后您将能够保留和释放它。

另外,请阅读 sergio 的编辑,了解它不是“正确的”单身人士。:p

此外,如果可以的话,转换为 ARC,您就不必担心这个了!

于 2012-09-03T16:06:03.723 回答
1

你做错了。考虑:

如果您多次调用activityViewForView,您将不会一遍又一遍地获得相同的对象。它只会初始化一个新对象并给你指向它的指针!!!

为了使这个东西成为单例,你必须将创建的对象存储在一个常量变量中,并确保在你的应用程序运行时始终引用这个对象(例如在 appDelegate 中声明指向这个对象的指针)。

然后每次调用activityViewForView时都必须检查常量变量是否指向有效对象。如果是,则返回有效对象,如果不是,则创建它并将其存储在常量静态变量中(仅创建一次)。

如果你确实使用了 ARC,那么一切就绪。如果没有,请释放您的对象(使用 dealloc 方法)

于 2012-09-03T16:17:59.373 回答