问题
How to fire block event in Objective C when UIViewController dealloc.
For example :
[PGMemberObj requestWithUserName:@"ab" andPassword:@"cc" andCallback:^(BOOL isSuc){
if (isSuc) {
NSLog("Login Suc.");
}else
{
NSLog("Login Failed");
}
}];
when i pop ViewController and dealloc was executed,i still receive Login Suc. or Login Failed Message. How to avoid this issue?
回答1:
Try with the following code:
__weak UIViewController *weakSelf = self;
[PGMemberObj requestWithUserName:@"ab" andPassword:@"cc" andCallback:^(BOOL isSuc){
if ([weakSelf isViewLoaded] && [weakSelf.view window])
//The view controller still exists AND it's being shown on screen
else
//Either dealloc'd or not on screen anymore
}];
It will test whether your view controller still exists AND is still on screen.
Just check for weakSelf
if you don't care if it's still being shown on screen.
if (weakSelf)
//Still exists
else
//dealloc'd
回答2:
If i understand you right, you want to stop the block from executing if your view controller is no longer alive? It's a little bit tricky since the block is sent to your PGMemberObj so your view controller no longer has any control over the block code. The cancelling has to be done where your block is executed, in your PGMemberObj requestWithUserName
method. Maybe you can have a __block variable set to your view controller and check if that has been deallocated before you fire the callback.
回答3:
Your completion block is typically a secondary thread.
You can try something like,
[PGMemberObj requestWithUserName:@"ab" andPassword:@"cc" andCallback:^(BOOL isSuc){
if (isSuc)
{
NSLog(@"Login Suc.");
[self.navigationController popViewControllerAnimated:YES];
}
else
{
NSLog(@"Login Failed");
UIAlertView *al=[[UIAlertView alloc]initWithTitle:@"Warning" message:@"Invalid username or password" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
[al show];
}
}];
回答4:
Best solution that I can think of would be to cancel the authentication if it's no longer needed. This means that your PGMemberObj
should contain a cancel
(or similar) method that would cancel its authentication process.
Another way would be to reset the block to nil
. In this case, your PGMemberObj
should have a member object to hold the authentication callback block, along with a copy
property.
You'd call the cancel
method, or reset the block
inside your dealloc
method.
回答5:
You could try with something like this:
__weak id *myWeakSelf = self;
[PGMemberObj requestWithUserName:@"ab" andPassword:@"cc" andCallback:^(BOOL isSuc) {
if (!myWeakSelf)
return;
if (isSuc) {
NSLog("Login Suc.");
}else
{
NSLog("Login Failed");
}
}];
Using the weak
reference to self will allow to detect when the block body is executed after self
has been deallocated. Indeed, in such case myWeakSelf
will be found to be nil
at the start of the block.
If you want to altogether prevent the block from being called, you need to setup some mechanism so that your PGMemberObj
object does know that the block should not be executed anymore. In this case, again, weak references might come to the rescue and you could set a weak
property of your PGMemberObj
so that it will be nil-ed when the requesting object is deallocated (in this case, you will only able to have one outstanding request).
来源:https://stackoverflow.com/questions/19512400/how-to-fire-block-event-in-objective-c-when-uiviewcontroller-dealloc