2

我有一个TableViewController带有触发[NSURLConnection sendAsynchronousRequest...]事件的按钮,并且还通过 performSegueWithIdentifier:sender: 加载模态序列,它针对一个小视图控制器。此覆盖视图控制器的目的是显示加载图形并在通过NSURLConnection.

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

除了解除覆盖视图控制器之外,一切正常,这会在调试器中引发警告,上面写着: “警告:在演示或解除正在进行时尝试从视图控制器解除!”

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

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

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

#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
4

3 回答 3

1

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

  • 您不需要覆盖以防止用户交互。只需使用 -NSApplication beginIgnoringInteractionEvents 关闭用户交互。

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

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

于 2012-11-14T05:23:37.987 回答
0

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

于 2013-01-11T16:14:50.653 回答
0

没关系,我搞定了。令人惊奇的是,半小时的休息时间可以整理一个人的思想……

该过程正在完成并在实际视图完成加载之前调用dismissViewController。从覆盖层上的 viewDidLoad 调用一个简单的委托就可以解决问题。

于 2012-11-14T05:20:39.123 回答