这个Objective-C代码是否会泄漏内存?

时间:2010-08-14 20:09:22

标签: objective-c cocoa cocoa-touch memory-leaks

我关注的一件事是我创建两个整数,但不释放它们。让它们成为NSIntegers会更好吗?

-(void) flipCoin {

    int heads = [headsLabel.text intValue];
    int tails = [tailsLabel.text intValue];

    if (random() %2 ==1 )
    {
        heads++;
    }
    else {
        tails++;
    }

    headsLabel.text = [NSString stringWithFormat:@"%d", heads] ;
    tailsLabel.text = [NSString stringWithFormat:@"%d", tails];

}

4 个答案:

答案 0 :(得分:7)

正如sha所说,局部变量在当前堆栈帧中分配。一旦当前函数调用返回,堆栈就会“弹出”,并且当前调用所占用的内存不会被放弃,直到它被下一次被推入堆栈部分的调用覆盖。

那么为什么我们必须发布这样的变量:

MyClass *myObject = [[MyClass alloc] init];

好吧,你实际上不必担心“myObject”。它就在你的整数堆栈中,当你的当前通话结束时它会被清理干净。

你需要担心的是myObject--指针指向的内存。它离开堆的某个地方。构造一个对象涉及向运行时询问一些半永久性的位置来放置它;该进程返回指针存储的内存地址。

allocrelease是Objective-C惯用语,它们在很大程度上取代了C malloc()free()函数,但所有这些都最终要求计算机预留内存堆,并且最终必须通过自动释放池,release消息或free()调用返回所有内存。

答案 1 :(得分:2)

没有。您的headstails变量是本地变量并存储在堆栈中。这不会导致泄漏。您在底部附近的两个NSString作业是使用便捷构造函数创建的,并将为您自动释放。

答案 2 :(得分:2)

所有默认数据类型(intcharBOOL等)都会自动为您管理,不会(也不会)被释放(出于所有意图和目的)。 NSInteger的行为同样如此,因为它们只是signed int s(或64位机器上的signed long s)。

您初始化的对象,例如NSStringNSArray通常必须被释放(除非它们是自动释放的,例如代码底部的NSString)。如果您曾在某事上致电-alloc-init,则必须稍后将其发布。如果你怀疑一个方法是否返回一个自动释放的对象,只需阅读文档(它会告诉你)。

此外,如果你想阅读内存管理,有很多很棒的资源可以教你(谷歌是一个很好的起点!),如果你认为你的代码泄漏了内存,那就运行它仪器,你将能够告诉......

答案 3 :(得分:2)

int是所谓的原始类型。它不是指向Objective-C对象的指针,因此您无法释放它。你甚至无法向它发送消息。

NSInteger也是一种原始类型,它是一种原始类型的typedef(通常很长)。所以你也不能释放它。

你需要释放什么?您需要通过发送new,alloc或包含副本的方法释放您获得的任何对象。您还需要释放已发送的对象。因此,必须释放以下所有局部变量:

-(void) foo
{
    NSString* aString  = [[NSString alloc] init];
    NSString* aString2 = [aString copy];
    NSString* aString3 = [someOtherString retain];
    NSString* aString4 = [@"some string" copy];
}

NB由于实现细节,你实际上可以逃脱不释放aString4,但你不必担心它。