バックグラウンドフェッチの完了後、ブロック完了ハンドラーの参照がゼロになる

ジョー・フラティアーニ

performFetchWithCompletionHandlerを使用してRSSフィードのバックグラウンドフェッチを実装しようとしていますが、完了ハンドラーを呼び出したい場合はnilです。

self.completionHandlerへの参照を保持する方法がありませんか?

self.completionHandlerを正しく宣言していますか?

アプリデリゲート内:

        //background fetch new RSS Feeds
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    MasterViewController *navigationController = [mainStoryboard instantiateViewControllerWithIdentifier:@"MasterView"];
    MasterViewController *viewController = navigationController;

    [viewController startParsingWithCompletionHandler2: ^ (UIBackgroundFetchResult completionHandler2){
        completionHandler (UIBackgroundFetchResultNewData);
    }];
}

メインビューコントローラの場合:

@property (nonatomic, strong) void (^completionHandler)(UIBackgroundFetchResult);


- (void) startParsingWithCompletionHandler2:(void (^)(UIBackgroundFetchResult))completionHandler2
{
    self.completionHandler = completionHandler2;
    if (self.completionHandler) {
        NSLog(@"completionHandler");
    }else{
        NSLog(@"not completionHandler");
    }
    [self performSelector: @selector(stopParsing) withObject: nil afterDelay: PARSER_TIME_LIMIT];
    [self.activityIndicator startAnimating];
    numberOfCompletedStories = 0;
    [self.parserArray removeAllObjects];
                                                        //check for RSS Site data updates
    for (int lCounter = 0; lCounter < self.rssFeedAddresses.count; lCounter ++) {
        RSSParser *parser = [[RSSParser alloc] init];
        [parser setDelegate: self];
        [self.parserArray addObject: parser];
        [parser setSiteTitle: [self.rssFeedNames objectAtIndex: lCounter]];
        [NSThread detachNewThreadSelector: @selector(begin:) toTarget: parser withObject: [self.rssFeedAddresses objectAtIndex: lCounter]];
    }
    if (self.completionHandler) {
        NSLog(@"#2  completionHandler");
    }else{
        NSLog(@"#2  not completionHandler");
    }
}

    - (void) storyIsDone//called when parser completed one rss feed
{
    numberOfCompletedStories ++;
    if (self.completionHandler) {
        NSLog(@"storyIsDone  YES completion handler %i", numberOfCompletedStories);
    }else{
        NSLog(@"storyIsDone  Not completion handler");
    }
    if (numberOfCompletedStories == self.rssFeedAddresses.count)
    {
            //if all the feeds are done cancel time-out timer
        [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(stopParsing) object: nil];
        [self.activityIndicator stopAnimating];
        [self.refreshControl endRefreshing];
        [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(reloadRSSfeeds) name: @"ReloadFeeds" object: nil];
        canRefresh = YES;
        NSLog(@"call back");
        [self performSelectorOnMainThread: @selector(callCompletion) withObject: self waitUntilDone: YES];
    }//else not yet complete
}

- (void) callCompletion
{
    if (self.completionHandler) {
        NSLog(@"callCompletion  YES completion handler");
        self.completionHandler (UIBackgroundFetchResultNewData);

    }else{
        NSLog(@"callCompletion  Not completion handler");
    }
}

出力は次のとおりです。

completionHandler
 #2  completionHandler
storyIsDone  Not completion handler
storyIsDone  Not completion handler
storyIsDone  Not completion handler
storyIsDone  Not completion handler
storyIsDone  Not completion handler
storyIsDone  Not completion handler
storyIsDone  Not completion handler
call back
callCompletion  Not completion handler
ジョー・フラティアーニ

クラスが正しく初期化されていません

バックグラウンドフェッチにperformFetchWithCompletionHandlerを使用する場合-メソッドが異なる順序で呼び出されるため、一部のオブジェクトが適切に初期化されません。

アプリがフォアグラウンドで起動されると、これらのメソッドが呼び出されます:(順番に)

initWithCoder awakeFromNib viewDidLoad dispatchLoadingOperation viewDidAppear

バックグラウンドフェッチを実行する場合、メソッドは次の順序で呼び出されます。

initWithCoder awakeFromNib startParsingWithCompletionHandler2 viewDidLoad dispatchLoadingOperation viewDidAppear

特に注意:vieDidLoadは、フォアグラウンドで実行されているときに解析を開始するdispatchLoadingOperationの前に呼び出されました。

バックグラウンドで実行している場合、viewDidLoadの前にstartParsingWithCompletionHandler2(バックグラウンドで実行しているときにも解析を開始します)が呼び出されました。

いくつかのオブジェクトがviewDidLoadで初期化されたため、解析が予想よりも早く開始され、解析結果を格納するために配列が初期化されませんでした。これは、アプリが起動していないように見えました。

完了ハンドラーのコールバックがnilであることを確認しているときに、実際の問題はクラスが正しくセットアップされていないことでした。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

バックグラウンドフェッチ完了ハンドラーの正しい使用

分類Dev

完了時にブロックハンドラーをゼロにする必要がありますか?

分類Dev

CoreLocationによる迅速なバックグラウンドフェッチロケーションの更新

分類Dev

PushViewControllerの後に完了すると、バックエンド完了ハンドラーがアプリをクラッシュさせます

分類Dev

Ubuntu 18.04 でランダムにフリーズし、「ウォッチドッグ: バグ: ソフト ロックアップ - CPU#11 が 22 秒間スタックしました」の後に「NMI ウォッチドッグ ハード ロックアップ」が表示される

分類Dev

DispatchQueue.main.asyncブロックで完了ハンドラーからの戻り値が更新されない

分類Dev

ブロック完了でバックグラウンドでオブジェクトを検索

分類Dev

Objective-Cで、バックグラウンドタスクの終了後に完了ハンドラーを呼び出すメソッドを実装する場合、スレッドセーフを判断する方法は?

分類Dev

フォアグラウンドプロセスがタスクの完了を完了したときにバックグラウンドプロセスを停止する方法

分類Dev

iOSバッチ画像のダウンロード完了とコールバック

分類Dev

複数のクロージャが実行されるとメソッドが完了するように、完了ハンドラをプールします

分類Dev

完了ハンドラクロージャは常にバックグラウンドスレッドで実行されていますか?

分類Dev

バックグラウンドループのあるforループ、完了あり?

分類Dev

バックグラウンドフェッチの実行後にユーザーに通知する

分類Dev

完了ハンドラーのSwiftジェネリック

分類Dev

大きなリポジトリをアップロードする場合、リポジトリのアップロードが完了している間に、別のターミナルタブで新しいブランチを作成してチェックアウトしても大丈夫ですか?

分類Dev

バックエンドタスクの完了後にフロントページを更新する方法

分類Dev

Bash:バックグラウンドでのジョブが完了したときに実行します

分類Dev

バックグラウンドの自動更新が完了する前にUbuntuがシャットダウンしないようにする

分類Dev

APIライブラリでのバックグラウンドフェッチ

分類Dev

SASでrsubmitを使用して、プロセスが完了するのを待たずにバックグラウンドで実行する方法

分類Dev

バックグラウンドでファイルをアップロードするのに助けが必要

分類Dev

バックグラウンドフェッチでローカル通知が起動しない

分類Dev

ドラッグ可能なコンテナにオーバーフローがある場合にのみ、ドロップ可能なオブジェクトをドラッグするときにjqueryuiドラッグアンドドロップ要素が切り取られます

分類Dev

親が最初に終了した場合、バックグラウンドプロセスは完了しますか?

分類Dev

バックグラウンド フェッチの列挙

分類Dev

約2000個のURLを確認した後、ウェブクローラーがハングアップする

分類Dev

RxJavaテスト:すべてのバックグラウンドタスクが完了するのを待つ方法

分類Dev

RxJavaテスト:すべてのバックグラウンドタスクが完了するのを待つ方法

Related 関連記事

  1. 1

    バックグラウンドフェッチ完了ハンドラーの正しい使用

  2. 2

    完了時にブロックハンドラーをゼロにする必要がありますか?

  3. 3

    CoreLocationによる迅速なバックグラウンドフェッチロケーションの更新

  4. 4

    PushViewControllerの後に完了すると、バックエンド完了ハンドラーがアプリをクラッシュさせます

  5. 5

    Ubuntu 18.04 でランダムにフリーズし、「ウォッチドッグ: バグ: ソフト ロックアップ - CPU#11 が 22 秒間スタックしました」の後に「NMI ウォッチドッグ ハード ロックアップ」が表示される

  6. 6

    DispatchQueue.main.asyncブロックで完了ハンドラーからの戻り値が更新されない

  7. 7

    ブロック完了でバックグラウンドでオブジェクトを検索

  8. 8

    Objective-Cで、バックグラウンドタスクの終了後に完了ハンドラーを呼び出すメソッドを実装する場合、スレッドセーフを判断する方法は?

  9. 9

    フォアグラウンドプロセスがタスクの完了を完了したときにバックグラウンドプロセスを停止する方法

  10. 10

    iOSバッチ画像のダウンロード完了とコールバック

  11. 11

    複数のクロージャが実行されるとメソッドが完了するように、完了ハンドラをプールします

  12. 12

    完了ハンドラクロージャは常にバックグラウンドスレッドで実行されていますか?

  13. 13

    バックグラウンドループのあるforループ、完了あり?

  14. 14

    バックグラウンドフェッチの実行後にユーザーに通知する

  15. 15

    完了ハンドラーのSwiftジェネリック

  16. 16

    大きなリポジトリをアップロードする場合、リポジトリのアップロードが完了している間に、別のターミナルタブで新しいブランチを作成してチェックアウトしても大丈夫ですか?

  17. 17

    バックエンドタスクの完了後にフロントページを更新する方法

  18. 18

    Bash:バックグラウンドでのジョブが完了したときに実行します

  19. 19

    バックグラウンドの自動更新が完了する前にUbuntuがシャットダウンしないようにする

  20. 20

    APIライブラリでのバックグラウンドフェッチ

  21. 21

    SASでrsubmitを使用して、プロセスが完了するのを待たずにバックグラウンドで実行する方法

  22. 22

    バックグラウンドでファイルをアップロードするのに助けが必要

  23. 23

    バックグラウンドフェッチでローカル通知が起動しない

  24. 24

    ドラッグ可能なコンテナにオーバーフローがある場合にのみ、ドロップ可能なオブジェクトをドラッグするときにjqueryuiドラッグアンドドロップ要素が切り取られます

  25. 25

    親が最初に終了した場合、バックグラウンドプロセスは完了しますか?

  26. 26

    バックグラウンド フェッチの列挙

  27. 27

    約2000個のURLを確認した後、ウェブクローラーがハングアップする

  28. 28

    RxJavaテスト:すべてのバックグラウンドタスクが完了するのを待つ方法

  29. 29

    RxJavaテスト:すべてのバックグラウンドタスクが完了するのを待つ方法

ホットタグ

アーカイブ