创建对象后自动释放对象时出错

发布于 2024-12-02 12:45:45 字数 1157 浏览 0 评论 0原文

我开始研究 IOS 开发,对于释放没有存储引用的对象有一些疑问。我查看了问题“释放没有指针的对象?”建议在对象创建后立即向对象发送自动释放消息,因此我尝试在以下代码中执行相同的操作:

int main(int argc, char *argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSURLResponse * response = nil;
    NSError * error = nil;
    NSData * data;

    data = [NSURLConnection
            sendSynchronousRequest: [[NSURLRequest requestWithURL: 
                                        [[NSURL URLWithString: @"http://www.google.it"] 
                                          autorelease] 
                                     ] autorelease]
                 returningResponse: &response
                             error: &error];

    [data writeToFile: @"/tmp/test.html"
           atomically:NO];

    [data release];
    [pool drain];

    return 0;
}

我还无法尝试在 XCode 中执行该程序,但我正在编译linux 和发送到 NSURLRequest 对象的自动释放消息会导致分段错误(我认为这不是由消息本身引起的,而是由于自动释放消息而试图释放对象的池耗尽引起的)。我发送到 NSURLRequest 对象的自动释放消息有什么问题?

我认为,如果像 requestWithUrl 这样的类方法的参考文档说它“创建并返回 URL 请求”,则意味着我有责任在使用完该对象后释放该对象,我错了吗?在进一步讨论其他问题之前,我想很好地理解这个内存管理规则。我希望我的问题不会太愚蠢;-)

呃,只是最后一个问题:我是否应该释放由同步请求?

预先感谢您的帮助!

I'm starting to look into IOS Development and I have some doubts about releasing objects for which I did not store a reference.. I gave a look at the question "Release an object without a pointer?" where it is suggested to send the autorelease message to the object immediately after its creation, and so I tried to do the same in the following piece of code:

int main(int argc, char *argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSURLResponse * response = nil;
    NSError * error = nil;
    NSData * data;

    data = [NSURLConnection
            sendSynchronousRequest: [[NSURLRequest requestWithURL: 
                                        [[NSURL URLWithString: @"http://www.google.it"] 
                                          autorelease] 
                                     ] autorelease]
                 returningResponse: &response
                             error: &error];

    [data writeToFile: @"/tmp/test.html"
           atomically:NO];

    [data release];
    [pool drain];

    return 0;
}

I could not try to execute the program in XCode yet, but I'm compiling under linux and the autorelease message sent to the NSURLRequest object causes a segmentation error (I think it is not caused by the message itself but by the pool drain that tries to release the object, due to the autorelease message). What's wrong with the autorelease message I've sent to the NSURLRequest object?

I think that if the reference doc for a class method like requestWithUrl says that it "Creates and returns a URL request" it means that I'm responsible to release the object when I've finished using it, am I wrong? I'd like to understand very well this memory management rules before going further with anything else.. I hope my questions are not too stupid ;-)

Uh, just one last question: should I release also the error and data objects returned by the synchrounous request?

Thank you in advance for any help!

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

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

发布评论

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

评论(4

非要怀念 2024-12-09 12:45:46

+requestWithURL: (和其他)方法已经返回自动释放的对象,因此您不应再向它们发送一个自动释放。

代码中的额外自动释放会使对象稍后过度释放并导致应用程序崩溃。

根据经验判断是否必须释放对象 - 仅当您使用名称中包含“alloc”、“new”、“copy”的方法创建对象时才需要释放。所有标准 API 都遵循此规则,您在开发自己的方法时也应遵循此规则。

因此更正后的代码将是:

int main(int argc, char *argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSURLResponse * response = nil;
    NSError * error = nil;
    NSData * data;

    data = [NSURLConnection
            sendSynchronousRequest: [NSURLRequest requestWithURL: 
                                            [NSURL URLWithString: @"http://www.google.it"]                                                                                
                 returningResponse: &response
                             error: &error];

    [data writeToFile: @"/tmp/test.html"
           atomically:NO];

    [pool drain];

    return 0;
}

PS 由于上述原因,不应释放数据和错误对象。

+requestWithURL: (and other) methods already return autoreleased objects so you should not send one more autorelease to them.

Extra autoreleases in your code make object over-released later and make app crash.

Rule of thumb to know if you must release an object - release required only if you create object using method that contains 'alloc', 'new', 'copy' in its name. All standard APIs follow this rule and you should follow it when developing your own methods.

So corrected code will be:

int main(int argc, char *argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSURLResponse * response = nil;
    NSError * error = nil;
    NSData * data;

    data = [NSURLConnection
            sendSynchronousRequest: [NSURLRequest requestWithURL: 
                                            [NSURL URLWithString: @"http://www.google.it"]                                                                                
                 returningResponse: &response
                             error: &error];

    [data writeToFile: @"/tmp/test.html"
           atomically:NO];

    [pool drain];

    return 0;
}

P.S. Neither data and error objects should be released for the above reasons.

徒留西风 2024-12-09 12:45:46

您的代码应如下所示:

int main(int argc, char *argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSURLResponse * response = nil;
    NSError * error = nil;
    NSData * data;

    data = [NSURLConnection
            sendSynchronousRequest: [NSURLRequest requestWithURL:[NSURL URLWithString: @"http://www.google.it"]] returningResponse:&response error: &error];

    [data writeToFile: @"/tmp/test.html"
           atomically:NO];

    [pool drain];

    return 0;
}

您不需要对使用该方法创建的对象调用 autorelease。\

您不需要释放 data错误。

所有使用下一个符号 NSClass *object = [NSClass classSomeMagicWords]; 返回对象的方法都将返回自动释放的对象,如果您不调用 retain,则不应释放该对象。

Your code should look like this:

int main(int argc, char *argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSURLResponse * response = nil;
    NSError * error = nil;
    NSData * data;

    data = [NSURLConnection
            sendSynchronousRequest: [NSURLRequest requestWithURL:[NSURL URLWithString: @"http://www.google.it"]] returningResponse:&response error: &error];

    [data writeToFile: @"/tmp/test.html"
           atomically:NO];

    [pool drain];

    return 0;
}

You don't need to call autorelease to your objects created with that methods.\

You don't need to release data and error.

All methods that returns object using next notation NSClass *object = [NSClass classSomeMagicWords]; will return autoreleased object, which you should not release if you don't call retain.

桜花祭 2024-12-09 12:45:46

您应该删除自动释放。在 iOS/Mac OSX 开发中,对于 Apple 提供的类,几乎有这样的规则:如果您使用不涉及 init 一词的方法创建对象,那么您将获得一个已经自动释放的对象。

例如:

NSString *blaah = [[NSString alloc] init];

将返回一个稍后需要释放的对象。

NSURL *googlelink = [NSURL URLWithString: @"http://www.google.it"];

另一方面会给你一个自动释放的对象,如果你再次释放它,它会崩溃。

You should remove the autoreleases. In the iOS/Mac OSX dev, with the Classes supplied by Apple it’s pretty much the rule that if you’re creating an object with a method that does not involve the word init, you’re given an already autoreleased object.

For example:

NSString *blaah = [[NSString alloc] init];

Would return an object that you need to release later.

NSURL *googlelink = [NSURL URLWithString: @"http://www.google.it"];

on the other hand will give you an autoreleased object and if you release it again, it will crash.

北凤男飞 2024-12-09 12:45:46

在 iOS 内存管理中,您只能拥有通过为其分配内存或复制创建的对象(方法以 alloc 开头或名称中包含“copy”)。

如果您拥有它们,您只需要释放/自动释放它们。 requestWithURLURLWithString 等方法返回已自动释放的对象。

检查 Apple 开发人员的此文档网站了解更多信息。

In iOS memory management, you only own objects you create by allocating memory for it or copying it (methods either starts with alloc or have "copy" in its name).

You only need to release/autorelease them if you own them. Methods such as requestWithURL or URLWithString returns already autoreleased objects.

Check this doc from Apple developer site for more information.

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