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

发布于 2024-08-26 08:35:40 字数 1060 浏览 4 评论 0原文

我是 Objective-C 的新手,我正在尝试了解内存管理以使其正确。

看完精彩
Cocoa 内存管理编程指南 作者:apple my唯一关心的是何时 实际上,自动释放的对象是在 iphone/ipod 应用程序中释放的。我的理解是在运行循环的末尾。但是什么定义了应用程序中的运行循环呢?

所以我想知道下面这段代码是否正确。假设一个对象

@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

此代码有效吗?

从苹果文本中我了解到从 functionA 返回的 NSString 在 functionB 范围内有效。我不确定它在 functionC 和 viewDidLoad 中是否有效。

谢谢!

I am new in objective-c and I am trying to understand memory management to get it right.

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. 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. I am not sure whether it is valid in functionC and in viewDidLoad.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

丿*梦醉红颜 2024-09-02 08:35:40

是的,您的函数是有效的,并且使用正确的 Cocoa 约定返回对象以保留/释放/自动释放/复制。

为了回答有关运行循环是什么的问题,在应用程序的 main() 函数中,它会调用 UIApplicationMain()。你可以想象 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];
    }
}

while 循环与 UIKit 实际执行的操作类似,每次通过 while 循环就像通过 runloop 一样,其中函数 getNextEvent 阻塞等待某个事件发生。所有的方法通常都是从像dispatchEvent:这样的东西中调用的。您可以尝试在其中一种方法(例如 IBAction)中设置断点,然后在顶部的调试器调用堆栈中查看处理事件和运行循环的 UIKit 方法的名称。由于每个方法都是从 while 循环中调用的,因此每次对对象调用 autorelease 时,该对象都会添加到运行循环中的外部池中。当当前事件完成分派后,池中的内容将被清空,并且这些对象最终会被发送释放消息。

最后一点。可以有多个自动释放池,它们并不总是位于事件循环的末尾。有时,您可能会在一次事件循环中分配数万个对象。发生这种情况时,您可以在自己的方法中设置额外的内部自动释放池,以减少自动释放池中自动释放对象的数量。自动释放池可以堆叠。

Yes, your functions are valid, and return objects using correct Cocoa conventions for retain/release/autorelease/copy.

To answer your question about what the runloop is, in your application's main() function, it invokes UIApplicationMain(). You can imagine UIApplicationMain looks something like this:

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. All of your methods are typically called from within something like 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. 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. 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.

梦回梦里 2024-09-02 08:35:40

该代码没有任何问题。它将按您的预期编译并运行。

functionA 返回的 NSString 对象在返回时仍然有效,因为它正在堆栈中传递给下一个人(functionB),后者现在保留跟踪它。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文