0

Core Animation は初めてで、デリゲートで drawLayer メソッドを使用して CALayer オブジェクトを実装する際に問題があります。

問題を非常に単純なテストに絞り込みました。Level2ViewController と呼ばれるセカンダリ viewController をプッシュする LBViewController という名前のメイン viewController があります。レベル 2 コントローラーの viewWillAppear: で、delegate=self を指定して CALayer オブジェクトを作成します (つまり、レベル 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

レベル 2 ビュー コントローラーをプッシュする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:) 。

上記のコードで作成box1したため、を使用します。最近、同様の問題に遭遇したとき、私は と を使用する別のデリゲート オブジェクトを持っていました。viewWillAppear:viewWillDisappear:initdealloc

注: に電話[super viewDidAppear:animated];viewWillAppearます。タイプミスまたはコピー/貼り付けの不具合のように見えます:-)

于 2012-09-04T09:06:26.650 に答える