0

わかりました..これがシナリオ全体です

コンセプトは、画面に複数の注文を表示し、ユーザーが左右にスライドして次の注文を表示できるようにすることです。注文が承認または拒否されると、注文ビューが下にスライドし、次のビューに置き換えられます。注文が終了している場合は前のビューに置き換えられます。

シンプルな UIScrollView といくつかのボタン (Accept & Decline) を含むタブバー ビューがあります。ViewDidLoad で Orders の配列を準備し、Nib ファイルで ViewControllers (合計注文に等しい) を初期化し、これらの ViewController のビューを ScrollView に追加し、ScrollView のコンテンツ サイズなどを設定します.. (垂直および水平スクロールの場合)

ユーザーが AcceptButton をタップすると、アニメーションが実行され、UIScrollView の Visible View が下にスライドし、スーパー ビューから削除されます。

アニメーション コードは次のように実行されます。

    BOOL lastPage = NO;
    BOOL ordersEmpty = NO;
    if (self.views.count == 1){
        ordersEmpty = YES;
        lastPage = YES;
    }

    UIViewController *controller2;
    if (self.views.count == page+1 && !ordersEmpty){
        lastPage = YES;
        controller2 = [self.views objectAtIndex:page-1];
    } else if (!ordersEmpty){
        controller2 = [self.views objectAtIndex:page+1];
    }
    [UIView animateWithDuration:1.5 animations:^{
        CGRect frame = controller.view.frame;
        frame.origin.y = frame.size.height + 100;
        controller.view.frame = frame;

        if (lastPage == NO){
            CGRect frame2 = controller2.view.frame;
            frame2.origin.x = frame.origin.x;
            controller2.view.frame = frame2;
        }else{
            // [self.scrollView scrollRectToVisible:controller2.view.frame animated:YES];
        }

    } completion:^(BOOL value){
        [controller.view removeFromSuperview];
        [self.views removeObject:controller];
        totalPages.text = [NSString stringWithFormat:@"%i", self.views.count];
        // currentPage.text = [NSString stringWithFormat:@"%i", 
        self.pageControl.numberOfPages = self.views.count;
        if (lastPage && !ordersEmpty){
            [self.scrollView scrollRectToVisible:controller2.view.frame animated:YES];
            lastPageMoving = YES;
        }else if (ordersEmpty){
            UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 30)];
            label.text = @"There are currently no notifications";
            label.textAlignment = UITextAlignmentCenter;
            label.center = CGPointMake(self.scrollView.frame.size.width/2, self.scrollView.frame.size.height/3);
            [self.scrollView addSubview:label];
            [label release];
            ofPages.text = @"";
            totalPages.text = @"";
            currentPage.text = @"";
            self.scrollView.contentSize = CGSizeMake(320, 267);
        }

        int i = 0;
        for (UIViewController *c in self.views)
        {
            c.view.frame = CGRectMake(self.scrollView.frame.size.width * i, 0, c.view.frame.size.width, c.view.frame.size.height);
            i++;
        }

        if (controller2 != nil)
        {
            if ([controller2 isKindOfClass:[CancelledController class]]) {
                self.acceptButton.hidden = YES;
                [self.declineButton setTitle:@"Close" forState:UIControlStateNormal];
                [self.declineButton setTitle:@"Close" forState:UIControlStateHighlighted];
            }else{
                self.acceptButton.hidden = NO;
                [self.declineButton setTitle:@"Decline" forState:UIControlStateNormal];
                [self.declineButton setTitle:@"Decline" forState:UIControlStateHighlighted];
            }
        }
    }];

アニメーションは正常に動作し、削除されたビューは割り当て解除されますが、

最後のビューが受け入れられると、アプリケーションは正確に [UIView animateWithDuration:animations:completion] メソッド呼び出しで exc_bad_access でクラッシュします。

NSZombies は、正確なリーク ポイント/原因を検出しません。

広範な調査の結果、ブロックの使用が原因である可能性があると思います..メモリ管理は問題ありません。

(コードはシミュレーターで正常に動作します-これまでにエラーはありません)

アニメーションがどのように機能するかを示すビデオを作成しました。これはシミュレーターのものなので、ここではエラーはありませんが、デバイスで実行すると、閉じるボタンを押すとすぐにアプリケーションがクラッシュします。

興味深いのは、最初に 2 番目の注文を閉じてから最初の注文を受け入れると、コードも正常に動作することです =( 非常に紛らわしい..!!

http://www.mediafire.com/?w1up9g9u6w0ucrn

プロジェクトは iOS 4.0 を対象としています

4

1 に答える 1

2

宣言UIViewController *controller2UIViewController *controller2 = nil;に変更することから始めることができます。その後、プロパティのみを使用することをお勧めします。そのため、行は次のようになります。

[controller.view removeFromSuperview];
[self.views removeObject:controller];

このプロパティのアクセサ メソッドを呼び出すことで置き換えられ、ivarcontrollerが保持されているかどうかを正確に把握できます。これは、使用している他のすべての ivar に有効です: lastPageMovingofPages、など - それらをプロパティに変更し、適切なメモリ管理を確認してください。totalPagescurrentPage

于 2012-06-02T13:57:56.560 に答える