以编程方式关闭视图控制器时发出警告
Posted
技术标签:
【中文标题】以编程方式关闭视图控制器时发出警告【英文标题】:Warning when dismissing view controller programatically 【发布时间】:2012-11-14 04:46:52 【问题描述】:我有一个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
【问题讨论】:
【参考方案1】:我不确定问题的确切原因,但这里有一些关于您的代码的观察结果。
您不需要覆盖来防止用户交互。只需使用 -NSApplication beginIgnoringInteractionEvents 关闭用户交互。
您不需要整个视图控制器来显示覆盖视图。只显示视图。例如,当 NSURLConnection 发生时,我经常在视图中间放置一个大的 UIActivityIndicatorView。
您不需要 NSOperationQueue 即可异步使用 NSURLConnection。它已经是异步的。只需创建 NSURLConnection 并等待委托消息到达。实际上,您正在自欺欺人,因为您正在设置辅助队列,消息到达该队列,然后您调用didSendData
,它在桌面上调用reloadData
- 在后台,这是非法的。如果您以正常方式执行此操作,您的委托消息将到达主线程,这正是您想要的。
【讨论】:
谢谢马特。我确实让它工作了,但我会按照你的建议尝试重新编码。【参考方案2】:没关系,我已经解决了。 令人惊奇的是,半小时的休息时间可以用来整理思绪……
在实际视图完成加载之前,该过程已经完成并调用了dismissViewController。覆盖层上 viewDidLoad 的简单委托调用可以解决问题。
【讨论】:
【参考方案3】:我也有这个问题。我注意到这是在我的 nib 文件中复制和粘贴按钮的结果。这样做的结果是我不得不在 IBActions 上绑两个 1 UIButton。
【讨论】:
以上是关于以编程方式关闭视图控制器时发出警告的主要内容,如果未能解决你的问题,请参考以下文章