处理retain / release / autorelease和类变量时遇到问题

时间:2012-10-20 12:45:37

标签: objective-c pointers memory-management retain

我在创建的测试应用程序中遇到了一些崩溃,我很确定它来自内存管理。以下是与此问题相关的三个问题:

问题A:

// Within singleton : GraphicsUtility
-(UIColor*)GetRandomColor
{
    float l_fRandomRedColor = [[MathUtility instance] GetRandomFloatNumberBetweenNumber:0.0f AndNumber:1.0f];
    float l_fRandomBlueColor = [[MathUtility instance] GetRandomFloatNumberBetweenNumber:0.0f AndNumber:1.0f];
    float l_fRandomGreenColor = [[MathUtility instance] GetRandomFloatNumberBetweenNumber:0.0f AndNumber:1.0f];

    return [UIColor colorWithRed:l_fRandomRedColor
                    green: l_fRandomGreenColor
                        blue: l_fRandomBlueColor
                        alpha: 255];
}

现在,我真的不知道如何在不重新发明轮子的情况下返回指向此对象的指针。由于方法colorWithRed:green:blue:alpha没有分配或创建(新)任何东西,我认为我不应该retain它。

我应该autorelease吗?

问题B:

现在在另一个类中获取对象时,如下所示:

// Within class : Test.
// mpCurrentPieceColor is a class variable.
mpCurrentPieceColor = [[GraphicsUtility instance] GetRandomColor];

由于我正在存储指向UIColor对象的指针,我是否需要再次保留它?

所以当我改变颜色时,我应该这样做吗?

// Within class : Test.
// mpCurrentPieceColor is a class variable.
[mpCurrentPieceColor release];
mpCurrentPieceColor = [[GraphicsUtility instance] GetRandomColor];
[mpCurrentPieceColor retain];

对我来说似乎完全错了......

问题C:

最后,在我的dealloc方法中,我这样做:

// Within class : Test
-(void) dealloc
{
    // never forget to call [super dealloc]
    [super dealloc];

    [mpCurrentPieceColor release];
}

这是对的吗?

我发现的“最佳”解决方案(也是更糟糕的:))是在某些地方使用保留...我没有崩溃但显然,我最终导致内存泄漏...任何帮助将不胜感激!谢谢!

2 个答案:

答案 0 :(得分:2)

答:不要自动释放。您正在调用的方法返回一个自动释放的对象;你只是扮演一个传球。

B& C:这些看起来对我很好。从逻辑上讲,您的颜色释放应该在[super dealloc]之前。

我不太确定你的“类变量”是什么意思。在一个单例中,您可以使用mpCurrentPieceColor作为强(或保留)属性,使用self.mpCurrentPieceColor访问它,并且释放/保留周围的分配将消失。 (当然,如果你切换到ARC,整个问题就会消失。)

另一点是“Product-> Analyze”菜单选项应该能够为您标记此类问题。

答案 1 :(得分:1)

问题A和B有点令人困惑,因为您没有使用正确的方法名称。 “get”在Cocoa中具有特殊含义,很少使用。您可能只想要“randomColor”作为名称。它应该返回一个自动释放的对象,但是colorWithRed:green:blue:alpha会这样做,所以除了看起来很好的名字之外。

假设你要返回一个自动释放的对象,你需要保留结果,并在完成后释放它。

你的dealloc肯定是不对的。 [super dealloc]将完成摧毁对象。然后你不能使用对象的片段(mpCurrentPieceColor)。你应该总是最后调用[super dealloc],因为这是销毁对象的最后一步。