1

我在做什么 ?

  1. 我目前正在为我的应用程序在没有互联网的情况下进行防崩溃。
  2. 我已经安装了Little snitch来暂时禁用网络访问。
  3. 发出请求并且如果响应为零,则触发“可达性测试”。下面代码中的 ReachabilityController 只是 Apple 提供的 Reachability 类的包装器。

此代码在其他地方有效吗?

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

错误发生在哪里

应用代理

错误

* * * -[ReachabilityController respondsToSelector:]:消息发送到已释放实例 0x12a71320

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

调试和仪器?

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

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

下图中“责任”部分的 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
        } 
}

可达性控制器.h

#import <UIKit/UIKit.h>
#import "Reachability.h"

@interface ReachabilityController : UIViewController
  -(void) checkReachability ;
@end

可达性控制器.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];
4

1 回答 1

1

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

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

于 2013-01-16T12:07:18.357 回答