Block_release deallocating UI objects on a background thread

后端 未结 3 1950
滥情空心
滥情空心 2020-12-03 17:33

One of the patterns presented at the WWDC 2010 \"Blocks and Grand Central Dispatch\" talk was to use nested dispatch_async calls to perform time consuming tasks on a backgro

相关标签:
3条回答
  • 2020-12-03 17:47

    You can use the __block storage type qualifier for such a case. __block variables are not automatically retained by the block. So you need to retain the object by yourself:

    __block UIViewController *viewController = [myViewController retain];
    dispatch_async(backgroundQueue, ^{
        // Do long-running work here.
        dispatch_async(dispatch_get_main_queue(), ^{
            [viewController updateUIWithResults:results];
            [viewController release]; // Ensure it's released on main thread
        }
    });
    

    EDIT

    With ARC, __block variable object is automatically retained by the block, but we can set nil value to the __block variable for releasing the retained object whenever we want.

    __block UIViewController *viewController = myViewController;
    dispatch_async(backgroundQueue, ^{
        // Do long-running work here.
        dispatch_async(dispatch_get_main_queue(), ^{
            [viewController updateUIWithResults:results];
            viewController = nil; // Ensure it's released on main thread
        }
    });
    
    0 讨论(0)
  • 2020-12-03 18:00

    In a thread, I just use [viewController retain]; then at the end of the thread use [viewController release]. It works and I don't use GCD~

    0 讨论(0)
  • 2020-12-03 18:07

    This worked for me (added a timer):

    [self retain]; // this guarantees that the last release will be on the main threaad
    dispatch_async(backgroundQueue, ^{
        // do something time consuming in background
        NSArray *results = ComputeBigKnarlyThingThatWouldBlockForAWhile();
    
        // use results on the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            [myViewController UpdateUiWithResults:results];
            [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(releaseMe:) userInfo:nil repeats:NO];
        });
    });
    - (void)releaseMe:(NSTimer *)theTimer {
        [self release]; // will be on the main thread
    }
    
    0 讨论(0)
提交回复
热议问题