同时调用多个ViewController实例会导致应用程序在AppDelegate中崩溃

时间:2013-01-16 08:32:38

标签: ios reachability appdelegate xcode-instruments memory-management

我在做什么?

  1. 我目前在没有互联网的情况下防范我的应用程序。
  2. 我暂时安装了 Little snitch 来进行网络访问。
  3. 当提出请求并且响应为零时,触发“可达性测试”。下面代码中的ReachabilityController只是Apple提供的Reachability类的包装器。
  4. 此代码是否可以在其他地方使用?

    该应用程序充满了在线请求,我从未在其他视图控制器中遇到此问题。如果互联网不可用,它会显示一条描述该状态的好消息。

    错误发生在哪里

    App Delegate

    错误

    * * * - [ReachabilityController respondsToSelector:]:发送到解除分配的实例0x12a71320的消息

    ReachabilityController显示描述错误状态的UIAlertView。警报视图显示为abt一秒钟,然后应用程序崩溃。

    Debuging and Instruments?

    NSLog(@“%p”,可达性); 记录与错误中相同的地址。的 0x12a71320 即可。不用说,这个地址每次运行都会有所不同。

    Instruments中的Zombies模板也指出了Reachability Controller。

    下图中“负责任”部分中的4行白色补丁包含应用的名称。

    Zombie object

    我期待什么?

    老实说,我不知道这种行为背后的原因。我相信它必须非常基础。

    我现在必须声明一个属性以保留“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 个答案:

答案 0 :(得分:1)

您可以将UIAlertView的委托设置为self。除非你有办法在UIAlertView发布之前保留你的ReachabilityController,否则这是一个悬空参考。

您是否需要UIAlertView与ReachabilityController进行交互?将nil作为代表传递可能是最简单的。