Objective c ObjC:直接分配给属性并释放它有多糟糕?
我想知道下面的代码对于有经验的objective-C程序员来说有多糟糕Objective c ObjC:直接分配给属性并释放它有多糟糕?,objective-c,coding-style,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]; 但我不确定它是否有足够的意义或者不会导致b
self.request = [[ASIHTTPRequest alloc] initWithURL:url];
[self.request release];
这绝对不是那么冗长
ASIHTTPRequest *tmp = [[[ASIHTTPRequest alloc] initWithURL:url];
self.request = tmp;
[tmp release];
但我不确定它是否有足够的意义或者不会导致bug
你觉得怎么样
更新:
我不想使用自动弹性池,因为我的应用程序将在内存有限的iphone上运行。当然要使用后者,尽管选择更具描述性的名称而不是
tmp
。您负责发布tmp
,但您不负责发布self.request
,至少在给定的上下文中不负责
或者,如果您不介意向自动释放池添加内容,只需执行以下操作:
self.request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
或
尽管选择一个更具描述性的名称而不是
tmp
,但一定要选择后者。您负责发布tmp
,但您不负责发布self.request
,至少在给定的上下文中不负责
或者,如果您不介意向自动释放池添加内容,只需执行以下操作:
self.request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
或
为什么不是这个
self.request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
或者,如果这是您编写的类或有其源代码,请创建一个新的类方法(而不是实例),该方法基本上执行相同的操作(假设NSURL*
参数):
为什么不是这个
self.request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
或者,如果这是您编写的类或有其源代码,请创建一个新的类方法(而不是实例),该方法基本上执行相同的操作(假设NSURL*
参数):
更新:我不想使用自动弹性池,因为我的应用程序将在内存有限的iphone上运行
一定要使用自动释放池!Cocoa touch框架本身使用它们;自己制作一两个自动释放对象并不会改变全局
没错,苹果警告你不要过度依赖iPhone上的自动释放池,比如在事件分派结束后,在池中耗尽之前放置大量对象,但过度避免自动释放池也会适得其反
没有什么是黑白的;涅磐在天堂
更新:我不想使用自动弹性池,因为我的应用程序将在内存有限的iphone上运行
一定要使用自动释放池!Cocoa touch框架本身使用它们;自己制作一两个自动释放对象并不会改变全局
没错,苹果警告你不要过度依赖iPhone上的自动释放池,比如在事件分派结束后,在池中耗尽之前放置大量对象,但过度避免自动释放池也会适得其反
没有什么是黑白的;涅磐在你的记忆中。你错过的不是冗长的差别,而是记忆管理的差别。
您经常会看到这样的代码:
ASIHTTPRequest * requestTmp = [[[ASIHTTPRequest alloc] initWithURL:url];
self.request = requestTmp;
[requestTmp release];
你应该考虑如果保留的属性发生了什么,旧的在Stter方法中被释放。
- 这意味着创建新的
请求
,refcount为1
self.request=request
,现在如果setRequest
看起来像:
- (void)setRequest:(ASIHTTPRequest*)aReq
{
[aReq retain];
[request release];
request = aReq;
}
这意味着对象保留了您传入的requestTmp
,并释放了旧的。requestTmp
的Refcount现在是2
- 在此调用之后,您可以释放您创建的原始
requestTmp
,并且您是安全的,因为保留requestTmp
-refcount的对象仍然是1
但是,如果您这样做:
self.request = [[ASIHTTPRequest alloc] initWithURL:url];
[self.request release];
您最终释放了对象保留的请求
,以供其使用。请注意,您正在释放对象的内部请求
,在原始情况下,您释放了tmp
,但对象保留了自己的保留引用
因此,结果与原始代码不同。您错过的不是详细程度的差异,而是内存管理的差异。
您经常会看到这样的代码:
ASIHTTPRequest * requestTmp = [[[ASIHTTPRequest alloc] initWithURL:url];
self.request = requestTmp;
[requestTmp release];
你应该考虑如果保留的属性发生了什么,旧的在Stter方法中被释放。
- 这意味着创建新的
请求
,refcount为1
self.request=request
,现在如果setRequest
看起来像:
- (void)setRequest:(ASIHTTPRequest*)aReq
{
[aReq retain];
[request release];
request = aReq;
}
这意味着对象保留了您传入的requestTmp
,并释放了旧的。requestTmp
的Refcount现在是2
- 在此调用之后,您可以释放您创建的原始
requestTmp
,并且您是安全的,因为保留requestTmp
-refcount的对象仍然是1
但是,如果您这样做:
self.request = [[ASIHTTPRequest alloc] initWithURL:url];
[self.request release];
您最终释放了对象保留的请求
,以供其使用。请注意,您正在释放对象的内部请求
,在原始情况下,您释放了tmp
,但对象保留了自己的保留引用
因此,结果与原始代码不同。我认为在这种情况下,添加到自动释放池没有什么大不了的,因为对象实际上不会被释放。这只是一个保留计数递减(不是免费的),因为(大概)属性分配增加了保留计数。当然,它会被释放。它将在自动释放池排空时释放。如果属性保留请求实例,它将不会被解除分配。使用自动释放池更简洁,但要付出一点点不可察觉的开销;我对术语使用不当。s/已发布/取消分配。我的观点是,将其添加到autorelease池并没有占用本来可以立即释放的内存,因为属性设置程序可能保留了该对象。正在添加到此中的自动释放池