IOS CATiledLayer crash

I have a PDF reader for iPad, where I use scrollview to display each page. I keep the page in sight and one page on each side of the page being viewed. I have separate views on portrait and landscape views. The portrait view shows one page, while the landscape viewer shows 2 pages.

When the iPad changes orientation, I unload the view for the old orientation and load the view for the new orientation. So say it was in portrait view, and then changed to landscape, the application unloads the portrait view and loads the landscape. All this works fine if the PDF is not big.

PDFs are drawn using tiledlayers. The application is scratched when changing orientation using large PDF files. The application only crashes if the orientation changes before all the tiles have been drawn. I assume that it is crashing because it is trying to draw tiles to represent what was unloaded. So, is there a way to stop drawing fragments when I unload the view?

+3
source share
2 answers

You need to set the CALayer delegate to zero, and then remove it from the supervisor. This stops rendering, after which you can safely disconnect.

- (void)stopTiledRenderingAndRemoveFromSuperlayer; {
    ((CATiledLayer *)[self layer]).delegate = nil;    
    [self removeFromSuperview];
    [self.layer removeFromSuperlayer];
}

In addition, be sure to call it from the main thread, otherwise spookies will be waiting for you.

+4
source

, , . CATiledLayer.content nil . , UIView , dealloc.

UIViewController dealloc, CATiledLayer , , .

- (void)dealloc
{
    // This works around a bug where the CATiledLayer background drawing 
    // delegate may still have dispatched blocks awaiting rendering after
    // the view hierarchy is dead, causing a message to a zombie object.
    // We'll hold on to tiledView, flush the dispatch queue, 
    // then let go of fastViewer.
    MyTiledView *tiledView = self.tiledView;
    if(tiledView) {
        dispatch_background(^{
            // This blocks while CATiledLayer flushes out its queued render blocks.
            tiledView.layer.contents = nil;

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                // Make sure tiledView survives until now.
                tiledView.layer.delegate = nil;
            });
        });
    }
}

, / Apple (StoreKit, CATiledLayer, UIGestureRecognizer) , @property (weak) id delegate, weak. , if != nil, . __strong Type *delegate = self.delegate, , , , nil, , , ( , ARC).

CATiledLayer , , . , , . - , .

content = nil dispatch_wait , . , , dealloc .

, , .

+3

All Articles