0

我是 Core Animation 的新手,并且无法在委托中使用 drawLayer 方法实现 CALayer 对象。

我已将问题缩小到一个非常简单的测试。我有一个名为 LBViewController 的主视图控制器,它推送一个名为 Level2ViewController 的辅助视图控制器。在2 级控制器中,在viewWillAppear: 中,我创建了一个CALayer 对象,它的delegate=self(即2 级控制器)。无论我是否真正实现了 drawLayer:inContext: 方法,我都有同样的问题——当我返回主 viewController 时,我遇到了僵尸崩溃。在分析器中,出现问题的对象似乎是 2 级 viewController 对象——它在弹出后被释放。

我尝试使用子类 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 (主控制器)中推送二级视图控制器的方法

- (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];
}
4

1 回答 1

2

您可能希望在nil释放委托对象之前将图层的委托设置为。所以在你Leve2ViewController这样做:

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

显然,这需要box1将其转换为字段(因此可以在 中访问viewWillDisappear:

由于您box1viewWillAppear:上面的代码中创建使用viewWillDisappear:. 最近,当我遇到类似的问题时,我有一个单独的委托对象,我在其中使用了initdealloc.

注意:您调用[super viewDidAppear:animated];. viewWillAppear看起来像错字或复制/粘贴故障:-)

于 2012-09-04T09:06:26.650 回答