如何在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
对象确实知道该块不应再被执行。 在这种情况下,弱引用可能会出现救援,您可以设置PGMemberObj
的weak
属性,以便在请求对象被释放时它将被PGMemberObj
(在这种情况下,您将只能有一个未完成的请求)。