我正在尝试理解,当在操作的完成块中引用Object时,让Object取消网络操作是否是dealloc方法是一个好主意。
我将尝试用一个例子来解释:
我有一个User
对象,其属性为picture
,User
有一个[self fetchPictureFromServer]
:
- (void)fetchPictureFromServer
{
NSDictionary *cmdParameters = ...; // set parameters
__block User *weakSelf = self;
[[AppClient sharedClient] sendCommand:@"getpicture" parameters:cmdParameters success:^(AFHTTPRequestOperation *operation, id response)
{
// success
UIImage *downloadedImage = ...; // get image from response
weakSelf.picture = downloadedImage; // set image to user's picture property
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// failed
}];
sendCommand
方法会创建(NSOperationQueue
)NSOperation
NSURLConnection
,及时发起weakSelf
下载图片。操作成功完成后,将调用成功块。
我正在使用- (void)dealloc
{
[[AppClient sharedClient] cancelAllCommandsForSender:self];
[super dealloc];
}
,因为我不希望该块保留我的User对象(并防止它被dealloc),我希望用户将负责取消现有的操作(如果存在)当他得到dealloc时
因此,用户dealloc方法如下所示:
EXC_BAD_ACCESS
但似乎虽然我正在取消dealloc方法中的操作,但有时成功块在用户获得dealloc之后被称为,并且我在行{weakSelf.picture = downloadedImage
中得到{{1}} 1}}。
为什么会这样?可能是操作尝试完成连接,即使它被取消了吗?
我知道如果我在块中仅使用self而不是weakSelf,则不会发生这种情况,因为该块将保留用户。但我不想要这种行为,我希望用户在发布时立即获得dealloc,即使存在提取操作。
的更新: 的 我注意到操作状态isFinished = YES,似乎对于我使用的库,当一个操作完成时,它不会立即执行成功块,而是使用主队列dispatch_async成功块。
所以恰当的是:
1.用户获取图像 - >创建一个操作
2.操作完成 - > dispatch_async成功块(仍未执行)
3.在执行成功块之前,用户dealloc - >取消他所有的操作(但不是步骤1中的操作,因为它处于isFinished状态)
4.现在执行成功块 - >尝试引用用户时,我得到EXC_BAD_ACCESS。
仍然不知道如何解决这个问题。
答案 0 :(得分:2)
[[AppClient sharedClient] sendCommand:@"getpicture" parameters:cmdParameters success:^(AFHTTPRequestOperation *operation, id response)
{
if(!operation.isCancelled)
{
// success
UIImage *downloadedImage = ...; // get image from response
weakSelf.picture = downloadedImage; // set image to user's picture property
}
}