如何在uiviewcontroller释放时在目标c中触发块事件

如何在UIViewController dealloc时触发Objective C中的块事件。

例如 :

[PGMemberObj requestWithUserName:@"ab" andPassword:@"cc" andCallback:^(BOOL isSuc){ if (isSuc) { NSLog("Login Suc."); }else { NSLog("Login Failed"); } }]; 

当我popupViewController和dealloc被执行,我仍然收到loginSuc。 或login失败消息。 如何避免这个问题?

尝试使用以下代码:

 __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 }]; 

它会testing你的视图控制器是否仍然存在,并仍然在屏幕上。 只要检查weakSelf如果你不在乎它是否仍然显示在屏幕上。

 if (weakSelf) //Still exists else //dealloc'd 

如果我理解你是正确的,你想停止执行,如果你的视图控制器不再活着? 由于块被发送到PGMemberObj,所以你的视图控制器不再控制块代码,这是有点棘手的。 取消必须在PGMemberObj requestWithUserName方法中执行的PGMemberObj requestWithUserName 。 也许你可以有一个__blockvariables设置到你的视图控制器,并检查是否已经释放,然后再触发callback。

您的完成块通常是辅助线程。

你可以尝试一下,

  [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]; } }]; 

我能想到的最好的解决scheme是取消authentication,如果不再需要的话。 这意味着你的PGMemberObj应该包含一个cancel (或者类似的)方法来取消它的authentication过程。

另一种方法是将块重置nil 。 在这种情况下, PGMemberObj应该有一个成员对象来保存身份validationcallback块以及一个copy属性。

你可以调用cancel方法,或者重置dealloc方法中的block

你可以尝试这样的事情:

 __weak id *myWeakSelf = self; [PGMemberObj requestWithUserName:@"ab" andPassword:@"cc" andCallback:^(BOOL isSuc) { if (!myWeakSelf) return; if (isSuc) { NSLog("Login Suc."); }else { NSLog("Login Failed"); } }]; 

使用对自身的weak引用将允许在self释放之后检测块体何时被执行。 事实上,在这种情况下, myWeakSelf在块的开始将被认定nil

如果要完全防止块被调用,则需要设置一些机制,以便PGMemberObj对象确实知道该块不应再被执行。 在这种情况下,弱引用可能会出现救援,您可以设置PGMemberObjweak属性,以便在请求对象被释放时它将被PGMemberObj (在这种情况下,您将只能有一个未完成的请求)。