1

私は何をやっている ?

  1. 現在、インターネットがない場合にアプリをクラッシュ防止しています。
  2. とりあえずネットアクセスを無効にするためにLittle snitchをインストールしました。
  3. リクエストが行われ、レスポンスが nil の場合、「到達可能性テスト」がトリガーされます。以下のコードの ReachabilityController は、Apple が提供する Reachability クラスの単なるラッパーです。

このコードは他の場所でも機能しますか?

アプリケーションはオンライン リクエストでいっぱいですが、他のビュー コントローラーでこの問題が発生したことはありません。インターネットが利用できない場合は、状態を説明する小さなメッセージが表示されます。

エラーはどこで発生しますか

アプリ デリゲート

エラー

* * * -[ReachabilityController RespondsToSelector:]: 割り当て解除されたインスタンス 0x12a71320 に送信されたメッセージ

ReachabilityController は、エラーの状態を説明する UIAlertView を表示します。アラート ビューが少しの間表示された後、アプリがクラッシュします。

デバッグとインストルメント ?

NSLog (@"%p", 到達可能性); エラーと同じアドレスを記録します。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 つのインスタンスがあります。インターネットが利用できないため、3 つの方法すべてがほぼ同時に到達可能性テストを要求します。3 つのすべてのメソッドには、上記のものと同様のメソッド宣言があります。3 つのメソッドはすべて、以下に示す「ローカル宣言」を使用してテストをトリガーします。

ReachabilityController *reachability = [ReachabilityController alloc] init];
[reachability checkReachability];
4

1 に答える 1

1

UIAlertView のデリゲートを自分自身に設定します。UIAlertView がリリースされるまで ReachabilityController を保持する方法がない限り、これはダングリング リファレンスです。

ReachabilityController と対話するために UIAlertView が必要ですか? nil をデリゲートとして渡すのが最も簡単かもしれません。

于 2013-01-16T12:07:18.357 に答える