khe*_*aud 4 iphone cocoa-touch memory-management release-management uinavigationcontroller
我在周末期间未能解决这个问题...我认为对Objective-C内存管理有很好的了解,但是这个很难解决.
总结一下上下文:我有一个吸引人的UIViewController,我在我的navigationcontroller中推送.这个UIViewController包含一个UIScrollView(在IB中创建).在UIViewController viewDidLoad()函数中,我添加了一个背景PDF(在UIview层的CATiledLayer子层中).
问题是,当我从导航控制器弹出UIViewController时,应用程序崩溃了.
使用Zombies工具和NSZombieLevel表明这是因为UIViewController被过度释放.
这是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
Run Code Online (Sandbox Code Playgroud)
在几小时内玩了//之后,我发现只有当我发出"newView.layer addSublayer:tiledLayer];"时才会发生过度发布的问题.如果没有添加subLayer,则UIViewController不会过度释放.
我按下这样推动我的ViewController:
PlanViewController *trailsController = [[PlanViewController alloc] initWithNibName:@"PlanView" bundle:nil ];
[self.navigationController pushViewController:trailsController animated:YES];
[trailsController release];
Run Code Online (Sandbox Code Playgroud)
我想知道我做错了什么.我一定会尊重内存管理指南.我认为问题来自CALayer.我在CALayer中尝试使用和不使用pdf,但它没有改变任何东西......
但无论我如何编码,它总是导致:** - [PlanViewController isKindOfClass:]:消息发送到解除分配的实例0xc641750**
乐器僵尸向我展示了过度发布:
88 PlanViewController Zombie -1 6909541120 0x64a6a00 0 UIKit - [UIView(Hierarchy)_makeSubtreePerformSelector:withObject:withObject:copySublayers:]
你有提示吗?
非常感谢你的帮助
解决了 !!!也许它可以帮助:
实际上,CATiledLayer会调用异步重绘.在发布UIViewController时,你必须对CATiledLayer说它的委托不再活着.我在我的CATiledLayer中添加了一个引用(assign),在我的dealloc函数中我做了:
self.PDFTiledLayer.contents=nil;
self.PDFTiledLayer.delegate=nil;
[self.PDFTiledLayer removeFromSuperlayer];
Run Code Online (Sandbox Code Playgroud)
我希望你不会失去我失去的那么多时间......