[英]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方法中释放旧属性,则应考虑发生的情况。
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.