同时调用多个 ViewController 实例会导致应用在 AppDelegate 中崩溃
Posted
技术标签:
【中文标题】同时调用多个 ViewController 实例会导致应用在 AppDelegate 中崩溃【英文标题】:Multiple instances of ViewController being called simultaneously cause the app to crash in AppDelegate 【发布时间】:2013-01-16 08:32:38 【问题描述】:我在做什么?
-
我目前正在为我的应用程序在没有互联网的情况下进行防崩溃。
我已经安装了Little snitch暂时禁用网络访问。
发出请求并且如果响应为零,则触发“可达性测试”。下面代码中的 ReachabilityController 只是 Apple 提供的 Reachability 类的包装器。
此代码在其他地方是否有效?
应用程序充满了在线请求,我在其他视图控制器中从未遇到过这个问题。如果互联网不可用,它会显示一条很好的描述状态的小消息。
错误发生在哪里
应用代理
错误
* * * -[ReachabilityController respondsToSelector:]:消息发送到已释放实例 0x12a71320
ReachabilityController 显示一个描述错误状态的 UIAlertView。警报视图会出现大约一秒钟,然后应用程序崩溃。
调试和仪器?
NSLog(@"%p", reachability); 记录与错误中相同的地址。 0x12a71320。不用说,这个地址在每次运行时都会有所不同。
Instruments 中的 Zombies 模板也在 Reachability Controller 中指出。
下图中“Responsible”部分的4行白色补丁包含应用的名称。
我期待什么?
老实说,我不知道这种行为背后的原因。我相信它必须非常基本。
与现在的本地声明相比,我是否必须声明一个属性才能保留“ReachabilityController”?
代码
发生崩溃的片段。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://myUrl"]];
NSData *authResponse = [NSData dataWithContentsOfURL:url];
dispatch_sync(dispatch_get_main_queue(), ^
if(authResponse == nil)
ReachabilityController *reachability = [[ReachabilityController alloc] init];
NSLog(@"%p", reachability);
[reachability checkReachability];
NSLog(@"%p", reachability);
return; // app crashes round here
ReachabilityController.h
#import <UIKit/UIKit.h>
#import "Reachability.h"
@interface ReachabilityController : UIViewController
-(void) checkReachability ;
@end
ReachabilityController.m
#import "ReachabilityController.h"
@interface ReachabilityController ()
@end
@implementation ReachabilityController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
// Custom initialization
return self;
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view.
- (void)viewDidUnload
[super viewDidUnload];
-(void) checkReachability
Reachability* internetAvailable = [Reachability reachabilityForInternetConnection];
NetworkStatus netStatus = [internetAvailable currentReachabilityStatus];
NSString *messageText;
if (netStatus == NotReachable)
messageText = [NSString stringWithFormat:@"iRestaurant has determined that internet access is not available at the moment"];
else
NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
NSString *ipAdress = [infoDict objectForKey:@"LookUpIpAdress"];
NSString *host = [NSString stringWithFormat:@"%@/iRestaurant", ipAdress];
Reachability *netReach = [Reachability reachabilityWithHostName:host];
NetworkStatus hostStatus = [netReach currentReachabilityStatus];
if (hostStatus == NotReachable)
messageText = [NSString stringWithFormat:@"Sorry, for your inconvenience. iRestaurant server is currently unreachable. The iRestaurant server may be down for maintenance. Please check back after 5 mins"];
else
messageText = [NSString stringWithFormat:@"Sorry, for your inconvenience. This service is temporarily unavailable. We are working very hard to get it back on track."];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"iRestaurant"
message:messageText
delegate:self
cancelButtonTitle:@"Done"
otherButtonTitles:nil];
[alertView show];
@end
更新:
更改问题的标题
只是最近的发现。有 3 个实例从在线服务器请求数据。由于无法上网,这三种方法几乎同时要求进行可达性测试。这三种方法都有与上面类似的方法声明。三种方法都使用如下所示的“本地声明”来触发测试。
ReachabilityController *reachability = [ReachabilityController alloc] init];
[reachability checkReachability];
【问题讨论】:
【参考方案1】:您将 UIAlertView 的委托设置为 self。除非您有办法在 UIAlertView 发布之前保留您的 ReachabilityController,否则这是一个悬空引用。
您是否需要 UIAlertView 与您的 ReachabilityController 进行交互?将 nil 作为委托传递可能是最简单的。
【讨论】:
我想我可以试试。此外,针对“可达性测试”提出了三个请求。第一个测试就足够了,所以我正在考虑将 NSNotification 引入图片中。你有什么感觉? 在 ReachabilityController 中将 UIAlertView 委托设置为 nil 解决了问题以上是关于同时调用多个 ViewController 实例会导致应用在 AppDelegate 中崩溃的主要内容,如果未能解决你的问题,请参考以下文章
从另一个 ViewController 调用一个 ViewController 的实例方法
在RelationshipSegue之后调用ViewController中的函数
如何在 ViewController 中调用所有自定义 UIView 的方法?