简体   繁体   English

什么时候释放自动释放的对象?

[英]When is an autoreleased object actually released?

I am new in objective-c and I am trying to understand memory management to get it right. 我是objective-c的新手,我正在努力理解内存管理以使其正确。

After reading the excellent 看完之后
Memory Management Programming Guide for Cocoa by apple my only concern is when actually an autoreleased object is released in an iphone/ipod application. Cocoa内存管理编程指南我唯一担心的是在iphone / ipod应用程序中实际释放自动释放的对象。 My understanding is at the end of a run loop . 我的理解是在运行循环结束时。 But what defines a run loop in the application? 但是什么定义了应用程序中的运行循环?

So I was wondering whether the following piece of code is right. 所以我想知道下面的代码是否正确。 Assume an object 假设一个对象

@implementation Test

- (NSString *) functionA {
    NSString *stringA;
    stringA = [[[NSString alloc] initWithString:@"Hello"] autorelease]
    return stringA;
}

- (NSString *) functionB {
    NSString *stringB;
    stringB = [self functionA];
    return stringB;
}

- (NSString *) functionC {
    NSString *stringC;
    stringC = [self functionB];
    return stringC;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString* p = [self functionC];
    NSLog(@"string is %@",p);
}

@end

Is this code valid? 这段代码有效吗?

From the apple text I understand that the NSString returned from functionA is valid in the scope of functionB . 从Apple文本据我所知,从NSString的返回泛函functionB的范围内有效。 I am not sure whether it is valid in functionC and in viewDidLoad . 我不确定它在functionCviewDidLoad中是否有效。

Thanks! 谢谢!

Yes, your functions are valid, and return objects using correct Cocoa conventions for retain/release/autorelease/copy. 是的,您的函数是有效的,并使用正确的Cocoa约定返回对象以进行retain / release / autorelease / copy。

To answer your question about what the runloop is, in your application's main() function, it invokes UIApplicationMain(). 要回答关于runloop是什么的问题,在应用程序的main()函数中,它会调用UIApplicationMain()。 You can imagine UIApplicationMain looks something like this: 你可以想象UIApplicationMain看起来像这样:

void int UIApplicationMain (int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName) {
    UIApplication *app = /* create app using principalClassName */;
    [app setDelegate:/* create delegate using delegateClassName */];
    while (![app shouldTerminate]) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        event = [app getNextEvent];
        [app dispatchEvent:event];
        [pool drain];
    }
}

That while loops is similar to what the UIKit is actually doing, and each trip through that while loop is like a trip through the runloop, where the function getNextEvent blocks waiting for some event to happen. while循环类似于UIKit实际执行的操作,并且每次循环都是通过runloop跳转,其中函数getNextEvent阻塞等待某些事件发生。 All of your methods are typically called from within something like dispatchEvent:. 所有方法通常都是从dispatchEvent:中调用的。 You might try setting a break point in one of your methods, like an IBAction, and looking in the debugger call stack way up at the top to see the names of the UIKit methods that handle the events and runloop. 您可以尝试在其中一个方法中设置断点,例如IBAction,并在顶部查看调试器调用堆栈,以查看处理事件和runloop的UIKit方法的名称。 Since each of your methods are called from within that while loop, each time you call autorelease on an object, that object is added to that outter pool in the run loop. 由于每个方法都是在while循环中调用的,因此每次在对象上调用autorelease时,该对象都会在运行循环中添加到该outter池中。 When the current event is finished being dispatched, the pool is drained, and those objects are finally sent release messages. 当调度完当前事件后,池就会耗尽,最后会发送这些对象的释放消息。

One last note. 最后一点。 There can be more than one autorelease pool, that aren't always at the end of the event loop. 可以有多个自动释放池,它们并不总是在事件循环的末尾。 Sometimes you might allocate tens of thousands of objects in one trip thorough the event loop. 有时您可以通过事件循环在一次旅行中分配数万个对象。 When that happens, you might setup additional inner auto release pools in your own methods to keep the number of autoreleased objects in autorelease pools down. 发生这种情况时,您可以在自己的方法中设置其他内部自动释放池,以保持自动释放池中自动释放对象的数量。 Auto release pools can stack. 自动释放池可以堆叠。

There's nothing wrong with that code. 这段代码没有错。 It will compile and run as you expect. 它将按预期编译和运行。

The NSString object returned from functionA is still valid upon return since it's being passed down the stack to the next guy ( functionB ) who is now keeping track of it. functionA返回的NSString对象在返回时仍然有效,因为它正在向下传递给下一个正在跟踪它的人( functionB )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM