简体   繁体   English

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

[英]ObjC: How bad is to directly assign to a property and the release it?

I'm wondering how bad is the following code for experienced objective-C programmers. 我想知道经验丰富的Objective-C程序员的代码有多糟糕。

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

It is definitely less verbose this 这绝对不那么冗长

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

But I'm not sure if it is meaningful enough or doesn't lead to bugs. 但我不确定它是否足够有意义或不会导致错误。

What do you think? 你怎么看?

UPDATE: I don't want to use autorelase pools as my app is going to run on iphone where memory is limited. 更新:我不想使用autorelase池,因为我的应用程序将在内存有限的iphone上运行。

UPDATE: I don't want to use autorelase pools as my app is going to run on iphone where memory is limited. 更新:我不想使用autorelase池,因为我的应用程序将在内存有限的iphone上运行。

Do use the autorelease pools! 使用自动释放池! Cocoa touch framework itself uses them; 可可触摸框架本身使用它们; making one or two autorelease 'ed objects yourself doesn't change the big picture. 自己制作一个或两个autorelease对象不会改变大局。

It's true Apple warns you against excessive reliance on autorelease pools on iPhone, like putting hundreads of objects before the pool gets drained after the conclusion of the event dispatch, but excessive avoidance of autorelease pools is also counter-productive! 苹果公司警告你不要过度依赖 iPhone上的自动释放池,例如在事件发送结束后池中的物品被放弃之前放置对象的hundreads,但过度避免自动释放池也会适得其反!

Nothing is black and white; 没有什么是黑白的; nirvana is in the middle way . 涅is是中间的方式

Definitely go with the latter, although choose a more descriptive name instead of tmp . 绝对选择后者,虽然选择更具描述性的名称而不是tmp You are responsible for releasing tmp , but you are not responsible for releasing self.request , at least not in the context given. 您有责任释放tmp ,但您不负责发布self.request ,至少不是在给定的上下文中。

Alternatively, if you don't mind adding things to the autorelease pool, simply do: 或者,如果您不介意向自动释放池添加内容,只需执行以下操作:

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

or 要么

self.request = [ASIHTTPRequest requestWithURL:url];

Why not this? 为什么不呢?

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

Or, if this is a class you wrote or have the source for, create a new class method (not instance) that does essentially the same thing (assuming NSURL * argument): 或者,如果这是您编写的类或具有源代码,请创建一个新的类方法(而不是实例),该方法基本上执行相同的操作(假设NSURL *参数):

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

What you missed is not the difference in verbosity but the memory management difference. 你错过的不是冗长的差异,而是记忆管理的差异。

You often see code like this: 你经常看到这样的代码:

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

You should consider what is happening if the property is retained and old one released in the setter method. 如果保留属性并在setter方法中释放旧属性,则应考虑发生的情况。

  • What this mean is that you create new request , refcount is 1. 这意味着您创建新request ,refcount为1。
  • self.request = request , now if setRequest looks like: self.request = request ,现在如果setRequest看起来像:

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

    This means that the object retained the requestTmp you passed in and released the old one. 这意味着该对象保留了您传入的requestTmp并释放了旧的。 Refcount of requestTmp is now 2. RefTount的requestTmp现在是2。

  • After this call you can then release your original requestTmp that you created and you are safe because the object retained the requestTmp - refcount is still 1. 在此调用之后,您可以释放您创建的原始requestTmp并且您是安全的,因为对象保留了requestTmp - refcount仍为1。

However if you do this: 但是,如果你这样做:

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

you end up releasing the request that the object retained for its use. 您最终会释放该对象retained供其使用的request Note that you are release object's internal request where in the original case you released the tmp but the object keeps it's own retained reference. 请注意,您是发布对象的内部request ,在原始情况下,您释放了tmp但该对象保留了它自己的保留引用。

So the result is different from the original code. 所以结果与原始代码不同。

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

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