如何允许在回调时释放对象?
Posted
技术标签:
【中文标题】如何允许在回调时释放对象?【英文标题】:How to allow the object to be released on callback? 【发布时间】:2011-01-16 13:09:57 【问题描述】:我有一个用 Objective C 编写的类,它通过连接到网络来完成一些工作。此类以异步方式完成此工作,并且用户提供了一个委托,该委托在操作完成后被调用(如果成功则响应,如果失败则返回错误)。当没有更多工作要做并且可以释放对象时调用委托。
现在我想支持一个用例,当用户在对该委托的调用中释放我的类的对象时。这是很自然的,因为我的类的实例不可重用。目前,当我的调用从回调返回时,它会尝试从离开的地方继续,却发现它已被释放。不用说,此时应用程序崩溃了。
我知道这是可以做到的,因为NSURLConnection
class 就是这样做的。在回调- (void)connectionDidFinishLoading:(NSURLConnection *)connection
中释放连接对象即可。我怎样才能做到这一点?
编辑:
下面是更好理解的代码:
@class MyRequest;
@protocol MyDelegate
- (void)completedRequest:(MyRequest*)request;
@end
@interface MyRequest : NSObject
id<MyDelegate> myDelegate;
//variables...
- (id)init;
- (id)initWithUrl:(NSString*)url delegate:(id<MyDelegate>)delegate;
- (void)dealloc;
- (void)fire;
@property (nonatomic, readonly) bool fired;
@property (nonatomic, readonly) NSInteger resultCode;
@property (nonatomic, readonly) NSString *errorMessage;
@end
用户创建MyRequest
的对象并发送fire
消息。 MyRequest
在内部使用 NSURLConnection
来完成这项工作。收到响应后,我调用用户给定的委托。
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
NSLog(@"In connectionDidFinishLoading...");
resultCode = RESULT_SUCCESS;
[urlConnection release];
[urlRequest release];
if (myDelegate != nil)
[myDelegate completedRequest:self];
【问题讨论】:
【参考方案1】:只需在调用委托回调之前添加[[self retain] autorelease]
即可延长对象的生命周期。这将导致它稍后发布,以便您完成。
另一种方法是使用NSObject
的performSelectorOnMainThread
方法。 performSelector...
机械会保留你的对象,调用方法,然后释放它。如果您让 performSelector 方法等到完成,那么您将遇到与现在相同的问题,因为您将在该调用期间被释放。如果您不等到它完成,那么您不应该有内存问题,但是完成后您将无能为力。如果这是可以接受的,那么你应该没问题。
【讨论】:
可以工作!在寻找线索时,我遇到了方法performSelectorOnMainThread
,它可用于调度方法调用。能解决问题吗?
这也可以解决你的问题,因为performSelector...
机器会保留你的对象,调用方法,然后释放它。如果您让performSelector
方法等到完成,那么您将遇到与现在相同的问题,因为您将在该调用期间被释放。如果您不等到它完成,那么您不应该有内存问题,但是完成后您将无能为力。如果这是可以接受的,那么你应该没问题。
我冒昧地根据您的 cmets 更新了答案。它使答案完整,我可以愉快地接受它。希望你不要介意。
完全没有 - 我正在考虑自己进行修改。以上是关于如何允许在回调时释放对象?的主要内容,如果未能解决你的问题,请参考以下文章
MTAudioProcessingTap EXC_BAD_ACCESS ,并不总是触发 finalize 回调。如何释放它?