iPhone WillResignative方法不';不能完成执行

iPhone WillResignative方法不';不能完成执行,iphone,objective-c,objective-c-blocks,Iphone,Objective C,Objective C Blocks,当采购订单进入后台或终止时,我的应用程序代理需要解锁/锁定我的microsoft SQL数据库上的采购订单 这是我的密码 - (void)applicationWillResignActive:(UIApplication *)application { NSLog(@"App will enter background"); if ([purchaseOrderIsLocked boolValue] && [purchaseOrderAutoID in

当采购订单进入后台或终止时,我的应用程序代理需要解锁/锁定我的microsoft SQL数据库上的采购订单

这是我的密码

    - (void)applicationWillResignActive:(UIApplication *)application {

    NSLog(@"App will enter background");
    if ([purchaseOrderIsLocked boolValue] && [purchaseOrderAutoID intValue] > 0) {
        NSLog(@"Unlock Purchase Order because app is in background %i", [purchaseOrderAutoID intValue]);
        [self unlockPurchaseOrderWithAutoID:self.purchaseOrderAutoID];
    }   

- (void)applicationWillEnterForeground:(UIApplication *)application {

   NSLog(@"App will enter foreground");

    if ([purchaseOrderIsLocked boolValue] == FALSE && [purchaseOrderAutoID intValue] > 0) {
        NSLog(@"Lock Purchase Order because app is coming back %i", [purchaseOrderAutoID intValue]);
        [self lockPurchaseOrderWithAutoID:self.purchaseOrderAutoID];
    }
}

-(void)lockPurchaseOrderWithAutoID:(NSNumber *)autoID {

NSLog(@"lock purchase order called with autoID=%i",[autoID intValue]);

    self.client = [SqlClientConnect connect];
    [self.client executeQuery:[NSString stringWithFormat:@"UPDATE PURCHASE SET PURCHASELOCK = '9999' WHERE PURCHASEORDERNO = '%i'", [autoID intValue]] 
          withCompletionBlock:^(SqlClientQuery *query) {

              if (query.succeeded) {
                  NSLog(@"locked purchase order");
                  purchaseOrderIsLocked = [NSNumber numberWithBool:YES];
              } else {
                  [self queryFailedWithError:query.errorText]; 
              } 
          }];
}

-(void)unlockPurchaseOrderWithAutoID:(NSNumber *)autoID {
    NSLog(@"unlock purchase order called with autoID=%i",[autoID intValue]);

    self.client = [SqlClientConnect connect];
    [self.client executeQuery:[NSString stringWithFormat:@"UPDATE PURCHASE SET PURCHASELOCK = '0' WHERE PURCHASEORDERNO = '%i'", [autoID intValue]] 
          withCompletionBlock:^(SqlClientQuery *query) {

              if (query.succeeded) {
                  NSLog(@"unlocked purchase order");
                  purchaseOrderIsLocked = [NSNumber numberWithBool:FALSE];
              } else {
                  [self queryFailedWithError:query.errorText]; 
              } 
          }];
   }

}
好吧,我觉得很好。。。然而,当我运行应用程序时,这是我按下home按钮时从日志中得到的结果

    2011-12-14 13:41:20.558 MA Mobile[2267:707] App will enter background
    2011-12-14 13:41:20.558 MA Mobile[2267:707] Unlock Purchase Order
     because app is in background 18 

2011-12-14 13:41:20.559 MA Mobile[2267:707] unlock purchase order called with autoID=18
它本应该一直发布“未锁定的采购订单”,但它没有 当我恢复应用程序时,这就是我得到的

2011-12-14 13:41:44.741 MA移动[2267:707]应用程序将进入前台 2011年12月14日13:41:44.973 MA Mobile[2267:707]未锁定的采购订单


就像它在恢复后运行块代码一样。这和街区有关吗?我应该做些不同的事情吗?

应用程序willresignactive速度非常快,因此在应用程序失去前景之前,您的任务可能还没有完成。此方法与其他一些具有类似名称的方法不同。系统并不是问你申请辞职是否合适,而是告诉你申请正在辞职


查看“在后台执行有限长度的任务”一节,了解如何让您的任务要求额外的时间来完成。

applicationWillResignActive
提供信息,告诉您您的应用程序不再可用于接收用户交互,当接到呼叫或弹出系统警报时,就会发生这种情况

在您的情况下,这是因为用户点击了home按钮,因此调用此方法,然后您的应用程序将进入后台,然后调用
ApplicationIdentinterBackground
。这是您希望执行此过程的地方,默认情况下,尽管您只有5秒钟的时间来完成需要执行的操作。但是,在iOS4中,您可以通过开始后台任务请求更多时间,最多10分钟

此方法的实现大约有五秒钟的时间来执行任何任务并返回。如果您需要额外的时间来执行任何最终任务,您可以通过调用从系统请求额外的执行时间。实际上,您应该尽快从ApplicationIdentinterBackground返回。如果该方法在时间用完之前未返回,则应用程序将终止并从内存中清除


一旦您跳过该块并返回到
-applicationIDResignative:
,您的应用程序将立即挂起,并且您启动的异步调用基本上已暂停。您需要让应用程序知道您需要花更多的时间在后台使用。您可以使用如下示例所示的代码来完成。有关长时间运行的后台任务的更多信息,请参阅《iOS应用程序编程指南》中的

此简单示例演示如何在代码中使用此功能:

-(void)unlockPurchaseOrderWithAutoID:(NSNumber *)autoID
{
  NSLog(@"unlock purchase order called with autoID=%i",[autoID intValue]);

  // Start long-running background task
  UIBackgroundTaskIdentifier bti = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];

  self.client = [SqlClientConnect connect];
  [self.client executeQuery:[NSString stringWithFormat:@"UPDATE PURCHASE SET PURCHASELOCK = '0' WHERE PURCHASEORDERNO = '%i'", [autoID intValue]] withCompletionBlock:^(SqlClientQuery *query) {
    if (query.succeeded) {
        NSLog(@"unlocked purchase order");
        purchaseOrderIsLocked = [NSNumber numberWithBool:FALSE];
    } else {
        [self queryFailedWithError:query.errorText]; 
    }
    // After we complete the asynchronous block, we need to let the system know we can suspend now
    if( bti != UIBackgroundTaskInvalid )
      [[UIApplication sharedApplication] endBackgroundTask:bti];
  }];
}

尝试添加返回;在功能结束时。这解决了问题。。。只有一个问题。有时,当我们不进入后台时,会调用此方法。总是使用UIBackgroundTaskIdentifier可以吗?是的,这不会造成任何伤害。此外,你需要决定这是否真的是你想要的。例如,您现在的通话有点不平衡。如果您只想在应用程序进入后台时解锁,则应使用该方法
-applicationidentinterbackgroun:
。如果你真的想在用户锁定其手机或其他任何东西时解锁,那么你使用的方法很好,但通常与
-applicationdidebecomeactive:
。超级有用的帖子相平衡。这有助于我解决一段时间以来一直存在的背景问题时关闭共享文档的问题。非常感谢。