0

このコード サンプルを参照してください。

dispatch_queue_t downloadQueue=dispatch_queue_create("test", NULL);

        dispatch_async(downloadQueue, ^{

            //do some core data fetching stuff
            //create UIImage            

            //Need to go back to the main thread since this is UI related
            dispatch_async(dispatch_get_main_queue(), ^{

                    if(someView)
                    {
                        [someView addSubview:self];
                    }
                }

            });
        });
        dispatch_release(downloadQueue);

このコードのメイン スレッド部分が実行されるまでに「someView」が存在しない場合はどうなるでしょうか。明らかに、これにより EXC_BAD_ACCESS クラッシュが発生しますが、この状況を処理する最善の方法は何かと考えています。ロードに数秒かかるページにユーザーが移動した後、現在のページがまだロードされている間に前のページに戻ることを決定した場合に最もよく発生します。

サブビューを追加しようとする前に、ある種のグローバルフラグをチェックすることを想像できましたが、それはハッキリしているようです。

4

2 に答える 2

0
dispatch_async(downloadQueue, ^{
    UIView* v = someView;

現時点someViewで存在しなくなった場合、および ARC を使用している場合vは nil であり、それをテストできます。

一方、someView存在する場合、および ARC を使用している場合は、それvへの強い参照であり、ブロックのネストの残りの部分で存在しなくなることはありません。次に、(その時点または後でブロックのメイン スレッド部分で)v.windowビューがまだインターフェイスにあるかどうかを調べることができます。そうでない場合は、続行する価値がありません。

于 2013-04-30T16:20:09.937 に答える
0
// Capture a strong reference to someView, to make sure it's still around later on.
__block UIView *v = someView;

//Need to go back to the main thread since this is UI related
dispatch_async(dispatch_get_main_queue(), ^{
   [v addSubview:self]
   // Release v (assuming ARC). If nothing else has retained someView, this means
   // that someView will be deallocated - but we're on the main thread, 
   // so that's fine. What we don't want is a background dealloc.
   v = nil;
});

また

// Capture a strong reference to someView, to make sure it's still around later on.
__weak UIView *weakRef = someView;


//Need to go back to the main thread since this is UI related
dispatch_async(dispatch_get_main_queue(), ^{
   // This is thread-safe because someView should only be de-alloced on the main thread.
   // consequently our access to weakRef is safe.
   UIView *strongRef = weakRef;
   [strongRef addSubview:self];
});

してはいけないことはこれです。

   UIView *strongRef = whatever;
    dispatch_async(downloadQueue, ^{
       dispatch_async(dispatch_get_main_queue(), ^{
          [someView addSubview:self]
       });
       // If, by the time we get here, the dispatch to the main queue has already run,
       // then we will send a release to someView on a background thread. If it's the last
       // remaining reference - and it might be, unlikely as it is, then we just dealloced 
       // a UIView in the background. This is bad. 
    });
于 2014-07-10T15:09:10.127 に答える