ObjC:直接分配给一个属性并释放它有多糟糕?

时间:2010-02-17 21:42:29

标签: objective-c coding-style

我想知道经验丰富的Objective-C程序员的代码有多糟糕。

self.request = [[ASIHTTPRequest alloc] initWithURL:url];
[self.request release];

这绝对不那么冗长

ASIHTTPRequest *tmp = [[[ASIHTTPRequest alloc] initWithURL:url];
self.request = tmp;
[tmp release];

但我不确定它是否足够有意义或不会导致错误。

您怎么看?

更新 我不想使用自动回收池,因为我的应用程序将在内存有限的iphone上运行。

4 个答案:

答案 0 :(得分:2)

  

更新:我不想使用自动回收池,因为我的应用程序将在内存有限的iphone上运行。

请使用自动释放池!可可触摸框架本身使用它们;自己制作一个或两个autorelease'ed对象不会改变大局。

苹果公司警告你不要对iPhone上的自动释放池上的过度依赖,比如在事件发送结束后池被耗尽之前放置对象的hundreads,但过度回避

没有什么是黑白的;必杀技属于middle way

答案 1 :(得分:1)

绝对选择后者,但选择更具描述性的名称而不是tmp。您有责任发布tmp,但您不负责发布self.request,至少不是在给定的上下文中。

或者,如果您不介意向自动释放池中添加内容,只需执行以下操作:

self.request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];

self.request = [ASIHTTPRequest requestWithURL:url];

答案 2 :(得分:1)

为什么不呢?

self.request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];

或者,如果这是您编写或拥有源的类,则创建一个基本相同的新类方法(不是实例)(假设NSURL *参数):

+ (ASIHTTPRequest *) requestWithURL:(NSURL *)url
{
     return [[[self alloc] initWithURL:url] autorelease];
}

答案 3 :(得分:0)

您错过的不是详细程度的差异,而是内存管理方面的差异。

您经常会看到如下代码:

ASIHTTPRequest * requestTmp = [[[ASIHTTPRequest alloc] initWithURL:url];
self.request = requestTmp;
[requestTmp release];

如果保留属性并在setter方法中释放旧属性,您应该考虑发生了什么。

  • 这意味着您创建新的request,refcount为1。
  • self.request = request,现在如果setRequest看起来像:

    - (void)setRequest:(ASIHTTPRequest*)aReq
    {
        [aReq retain];
        [request release];
        request = aReq;
    }
    

    这意味着该对象保留了您传入的requestTmp并释放了旧对象。 #{1}}的引用现在为2。

  • 在此次通话后,您可以释放您创建的原始requestTmp,并且您是安全的,因为保留requestTmp的对象 - 引用计数仍为1.

但是如果你这样做:

requestTmp

您最终会释放对象self.request = [[ASIHTTPRequest alloc] initWithURL:url]; [self.request release]; 供其使用的request。请注意,您是发布对象的内部retained,在原始情况下,您释放了request,但该对象保留了它自己的保留引用。

所以结果与原始代码不同。