2012-05-18 2 views
0

Я новичок в Core Animation и не могу реализовать объект CALayer с помощью метода drawLayer в делегате.Деление CALayer вызывает крушение зомби - почему?

Я сузил проблему до очень простого теста. У меня есть главный viewController с именем LBViewController, который подталкивает дополнительный viewController, называемый Level2ViewController. В контроллере уровня 2 в viewWillAppear :, я создаю объект CALayer с его делегатом = self (т. Е. Контроллером уровня 2). Я действительно реализую drawLayer: inContext: метод У меня такая же проблема - когда я возвращаюсь к основному viewController, я получаю сбой в зомби. В профилировщике кажется, что объект в беде - это объект viewController уровня 2, который отменяется после его выталкивания.

Я попытался использовать объект класса CALayer подкласса, а не делегат, и он отлично работает. Если я прокомментирую назначение делегата, он также отлично работает. Я хотел бы понять, почему делегирование вызывает эту проблему. Любые советы высоко ценится.

Вот мой код ---

Level2ViewController

@implementation Level2ViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    CALayer *box1 = [[CALayer alloc] init]; 
    box1.delegate = self; // problem disappears if I comment out this assignment 
    box1.backgroundColor = [UIColor redColor].CGColor; 
    box1.frame = CGRectMake(10,10,200,300); 
    [self.view.layer addSublayer:box1]; 
    [box1 setNeedsDisplay]; 

} 

// makes no difference whether or not this method is defined as long 
// as box1.delegate == self 
- (void)drawLayer:(CALayer *)theLayer inContext:(CGContextRef)theContext 
{ 
    CGContextSaveGState(theContext); 
    CGContextSetStrokeColorWithColor(theContext, [UIColor blackColor].CGColor); 
    CGContextSetLineWidth(theContext, 3); 
    CGContextAddRect(theContext, CGRectMake(5, 5, 40, 40)); 
    CGContextStrokePath(theContext); 
    CGContextRestoreGState(theContext); 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

@end 

Метод в LBViewController (главный контроллер), который выталкивает вид контроллер уровня 2

- (IBAction)testAction:(id)sender { 
    Level2ViewController *controller = [[Level2ViewController alloc] 
            initWithNibName:@"Level2ViewController" bundle:nil]; 
    controller.title = @"Level2"; 

    // this push statement is where the profiler tells me the messaged zombie has been malloc'ed 
    [self.navigationController pushViewController:controller animated:YES]; 
    [controller release]; 
} 
+0

Из того, что я вижу в документации, делегат CALayer обычно является UIView, попробуйте сделать box1.delegate = self.view; –

+0

Я не могу сделать это с текущей структурой моей программы. Потому что метод делегата находится в контроллере. Но я попробую подклассифицировать UIView и создать там объект CALayer, сделав подклассовое представление делегатом. Я опубликую результаты, когда закончится. – lp1756

+0

нормально звучит как план, но почему вы не хотите подкласса CALayer? –

ответ

2

You может захотеть установить делегат слоя на nil перед тем, как объект делегата будет выпущен. Так что в вашем Leve2ViewController сделать это:

-(void)viewWillDisappear:(BOOL)animated 
{ 
    if (box1) { 
     box1.delegate = nil; 
    } 
    box1 = nil; 
} 

Очевидно, что это требует, чтобы box1 превращается в поле (так он доступен в viewWillDisappear:)

Поскольку вы создаете box1 в viewWillAppear: код выше использует viewWillDisappear:. Недавно, когда у меня возникла аналогичная проблема, у меня был отдельный объект-делегат, в котором я использовал init и dealloc.

Примечание: вы вызываете [super viewDidAppear:animated]; в viewWillAppear. Похоже на опечатку или скопируйте/вставьте сбой :-)

Смежные вопросы