【问题标题】:Objective-C blocks: How to set an object to nil which uses block-based callback mechanism?Objective-C 块:如何将使用基于块的回调机制的对象设置为 nil?
【发布时间】:2015-09-16 10:40:25
【问题描述】:

我有一个 NetworkManager 类,它负责连接到基于 JSON 的 Web 服务并返回服务器响应。我正在使用完成处理程序块从 NetworkManager 返回成功或错误响应(在内部,NetworkManager 使用基于委托的 NSURLConnection)。

NetworkManager *objNetworkManager= [[NetworkManager alloc]init];

[objNetworkManager setCompletionHandler:^(NSDictionary *resp, BOOL isSuccess){
    if (isSuccess) {

    }else{

    }
}];

[objNetworkManager initiateUrlRequestWithInput:jsonRequestInput];

现在一切正常,我的网络请求使用此 NetworkManager 类按预期工作。我担心的是,我每次进行 Web 服务调用时都会分配一个 NetworkManager 实例。但是,我应该在哪里将 objNetworkManager 设置为 nil?因为它使用块回调,我不确定如何有效地处理内存。请指教!!

【问题讨论】:

  • 我通过(id) 类型参数的方法管理了这种情况。该方法将nil设置为对象(id)
  • Harvant,你能详细说明一下吗!!

标签: ios objective-c objective-c-blocks


【解决方案1】:

这是我的看法:

如果您没有创建引用循环或任何泄漏,ARC 会自动为您处理。例如,如果 VC1 实例化 NetworkManager 并发布所有内容,则您退出 VC1 并释放它,然后 NetworkManager 引用也将被释放。

如果您真的想主动发布 NetworkManager,那么您可以在成功和错误完成块中执行此操作。我就是这样做的:)。

编辑:示例:

__weak MyViewController *aBlockSelf = self;

// Save User Preferences (/ics/markavailable)
self.requestHandler = [[MyRequestHandler alloc] initWithEndPoint:@"/fetch/request" body:aBodyData container:self.navigationController.view loadingOverlayTitle:@"Loading..." successHandler:^(NSDictionary *iResponse) {
    // Do success handling

    aBlockSelf.requestHandler = nil;
} andErrorHandler:^(NSString *iMessage, NSString *iKey, NSInteger iErrorCode, BOOL iIsNetworkError) {
   // Do success handling

   aBlockSelf.requestHandler = nil;
}];

[self.requestHandler executeRequest];

要了解保留周期,请查看this thread

【讨论】:

  • 那么,你的意思是我应该将 objNetworkManager 初始化为 __block 变量。因为,在块实现中只能修改 __block 变量。
  • 另外,您能否告诉我如何避免块中的保留周期和内存泄漏。
【解决方案2】:

如果可以同时调用web服务,可以在公共数据中使用NSMutableArray来保存管理器。

//Public data manager class add a NSMutableArray to save managers.
@property (nonatomic, strong) NSMutableArray *requestingManager;

NetworkManager *objNetworkManager= [[NetworkManager alloc]init];
[objNetworkManager setCompletionHandler:^(NSDictionary *resp, BOOL isSuccess){
    //remove when finish
    [[PublicData instance].requestingManager removeObject:objNetworkManager];
    if (isSuccess) {

    }else{

    }
}];
[objNetworkManager initiateUrlRequestWithInput:jsonRequestInput];
//add manager when request
[[PublicData instance].requestingManager addObject:objNetworkManager];

删除objNetworkManager后,objNetworkManager不会被保留,会释放,里面的block会自动置为nil。

【讨论】:

    猜你喜欢
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多