以编程方式解除视图控制器时发出警告

时间:2012-11-14 04:46:52

标签: ios uiviewcontroller xcode4.5 objective-c-2.0 uistoryboardsegue

我有一个带有触发TableViewController事件的按钮的[NSURLConnection sendAsynchronousRequest...],还通过performSegueWithIdentifier:sender:加载一个模态segue,它定位一个小视图控制器。此叠加视图控制器的目的是显示加载图形,并在数据通过NSURLConnection发送时阻止用户交互。

NSURLConnection的完成功能块中,我调用了一种删除TableViewController中数据的方法(它只是一个批量列表),然后在覆盖视图上调用dismissViewControllerAnimated:completion:控制器。

除了解除覆盖视图控制器之外,一切都有效,它在调试器中抛出一个警告: “警告:正在进行演示或解雇时尝试从视图控制器中解除!”

我发现了有关此错误的各种问题和答案,特别是关于使用performSelector:object:withDelay方法的问题,但到目前为止还没有任何效果。

这特别令人讨厌,因为我在应用程序的另一个区域使用了类似的过程,除了从选择UITableViewCell调用dismissViewController,这样工作正常......

我的代码的相关位如下所示:

#import "ViewBatch.h"

@interface ViewBatch ()
@property (strong, nonatomic) LoadingOverlayViewController *loadingOverlay;
@end

@implementation ViewBatch
@synthesize loadingOverlay;

....

- (IBAction)exportBatch:(id)sender
{
    if ([productArray count] > 0) {
        [self performSegueWithIdentifier:@"loadingSegue" sender:self];
        [self processData];
    }
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"loadingSegue"]) {

        loadingOverlay = segue.destinationViewController;
    }
}

- (void)processData
{

    // Code to create a file and NSURLRequest...
    // ....

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:urlRequest
                                       queue:queue
                           completionHandler:^(NSURLResponse *response, NSData *responseData, NSError *error) {
                               if ([responseData length] > 0 && error == nil)
                               {
                                   // Not used for this request yet...
                               }
                               else if ([responseData length] == 0 && error == nil)
                               {
                                   // Success...
                                   [self didSendData];
                               }
                               else if (error != nil)
                               {
                                   // Connection error...
                                   NSLog(@"Error: %@", error);
                               }
                          }];
}

- (void)didSendData
{
    // Reset the batch...

    [productArray removeAllObjects];
    [self.tableView reloadData];

    [loadingOverlay dismissViewControllerAnimated:YES completion:NULL];
}

加载视图控制器只是:

#import <UIKit/UIKit.h>

@interface LoadingOverlayViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *statusLabel;
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;

@end

....

....

#import "LoadingOverlayViewController.h"

@interface LoadingOverlayViewController ()
@end

@implementation LoadingOverlayViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.activityIndicator startAnimating];
}

@end

3 个答案:

答案 0 :(得分:1)

我不确定问题的确切原因,但这里有一些关于你的代码的观察结果。

  • 您不需要叠加以防止用户互动。只需关闭与-NSApplication beginIgnoringInteractionEvents的用户交互。

  • 您不需要整个视图控制器来显示叠加视图。只是显示视图。例如,我经常在我的视图中间放置一个大的UIActivityIndi​​catorView,同时发生NSURLConnection。

  • 您不需要NSOperationQueue即可异步使用NSURLConnection。它已经是异步的。只需创建NSURLConnection并等待委托消息到达。事实上,你正在自我鼓励,因为你正在设置一个辅助队列,消息到达该队列,你在桌面上调用didSendData调用reloadData - 在后台,这是非法的。如果以正常方式执行此操作,您的委托消息将到达主线程,这正是您想要的。

答案 1 :(得分:0)

没关系,我明白了。 令人惊讶的是半小时休息可以组织一个人的想法......

该过程正在完成并在实际视图甚至完成加载之前调用dismissViewController。来自覆盖的viewDidLoad的简单委托调用将事情排序。

答案 2 :(得分:0)

我也有这个问题。我注意到这是复制并粘贴我的nib文件中的按钮的结果。结果是我不得不将IBActions绑定两个1 UIButton。