Memory issue / reboot using navigation manager and view containing sub CALayer

I was not able to solve this problem during the weekend ... I thought I was good at Objective-C memory management, but this is very difficult to solve.

In the final context: I have a subordinate UIViewController that I insert into my navigation controller. This UIViewController contains a UIScrollView (created in IB). In the UIViewController viewDidLoad () function, I add a background PDF (in the CATiledLayer sublayer of the UIview layer ).

The problem is that when I exit the UIViewController from the navigation controller, the application crashes.

Using the Zombies and NSZombieLevel tools shows that this is because the UIViewController is being re-released .

Here is the UIViewController:

@interface PlanViewController : UIViewController <UIScrollViewDelegate> { UIScrollView *panelScrollView; UIView *myContentView; CGPDFDocumentRef myDocumentRef; CGPDFPageRef myPageRef; } @property (nonatomic, retain) IBOutlet UIScrollView *panelScrollView; @property (nonatomic, retain) UIView *myContentView; @end @implementation PlanViewController @synthesize panelScrollView; @synthesize myContentView; - (void)viewDidLoad { [self setTitle:@"Plan"]; myDocumentRef = CGPDFDocumentCreateWithURL((CFURLRef)[[NSBundle mainBundle] URLForResource:@"salonMap" withExtension:@"pdf"]); myPageRef = CGPDFDocumentGetPage(myDocumentRef, 1); CGRect pageRect = CGRectIntegral(CGPDFPageGetBoxRect(myPageRef, kCGPDFCropBox)); CATiledLayer *tiledLayer = [[CATiledLayer alloc] init]; [tiledLayer setDelegate:self]; [tiledLayer setTileSize:CGSizeMake(1024.0, 1024.0)]; [tiledLayer setLevelsOfDetail:4]; [tiledLayer setLevelsOfDetailBias:8]; [tiledLayer setFrame:pageRect]; UIView *newView = [[UIView alloc] initWithFrame:pageRect]; [newView.layer addSublayer:tiledLayer]; [newView setTag:555]; [self setMyContentView:newView]; [newView release]; [tiledLayer release]; [panelScrollView setDelegate:self]; [panelScrollView setContentSize:pageRect.size]; [panelScrollView setMaximumZoomScale:5]; [panelScrollView addSubview:myContentView]; [panelScrollView setClipsToBounds: YES]; [panelScrollView setMaximumZoomScale:20.0]; [panelScrollView setMinimumZoomScale:1.0]; [panelScrollView setZoomScale:1]; [self initPinsOnMap]; } - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0); CGContextFillRect(ctx, CGContextGetClipBoundingBox(ctx)); CGContextTranslateCTM(ctx, 0.0, layer.bounds.size.height); CGContextScaleCTM(ctx, 1.0, -1.0); CGContextConcatCTM(ctx, CGPDFPageGetDrawingTransform(myPageRef, kCGPDFCropBox, layer.bounds, 0, true)); CGContextDrawPDFPage(ctx, myPageRef); } - (void)dealloc { [panelScrollView release]; [myContentView release]; CGPDFDocumentRelease(myDocumentRef), myDocumentRef = NULL; myPageRef = NULL; [super dealloc]; } @end 

After you played with // for several hours, I found that the issue released above occurs if I "[newView.layer addSublayer: tiledLayer];". If no additional sublider is added, the UIViewController will not be removed.

I click on my ViewController as follows:

 PlanViewController *trailsController = [[PlanViewController alloc] initWithNibName:@"PlanView" bundle:nil ]; [self.navigationController pushViewController:trailsController animated:YES]; [trailsController release]; 

I am wondering what I am doing wrong. I am sure to respect the memory management guide. I think the problem comes from CALayer. I tried to use without using PDF in CALayer, but nothing changes ...

But no matter how I code it, it always results in: ** - [PlanViewController isKindOfClass:]: the message was sent to the freed instance 0xc641750 **

Zombie tools show me an overabundance:

88 PlanViewController Zombie -1 6909541120 0x64a6a00 0 UIKit - [UIView (Hierarchy) _makeSubtreePerformSelector: withObject: withObject: copySublayers:]

Do you have a clue?

Many thanks for your help

+4
source share
1 answer

SOLVE !!! Maybe this can help:

In fact, asynchronous redraws are called by CATiledLayer. When you release the UIViewController, you must tell CATiledLayer that its delegate is no longer alive. I added a link (assign) to my CATiledLayer and my dealloc function:

 self.PDFTiledLayer.contents=nil; self.PDFTiledLayer.delegate=nil; [self.PDFTiledLayer removeFromSuperlayer]; 

Hope you don’t lose as much time as I lost ...

+5
source

Source: https://habr.com/ru/post/1340599/


All Articles