IOS: NavigationController switch UIViewcontrollers , EXC_BAD_ACCESS EXC_I386_GPFLT 错误

IOS: NavigationController switch UIViewcontrollers , EXC_BAD_ACCESS EXC_I386_GPFLT error

当我点击按钮将 ViewController ViewController 推送到 ViewController2 时, 第一次还好,当我return从ViewController2ViewController, 第二次单击按钮到 ViewController2 , 发生错误:EXC_BAD_ACCESS EXC_I386_GPFLT.

这是我的 ViewController.m:

#import "ViewController.h"
#import "ViewController2.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.navigationController.delegate = self;
    self.circleAnimator = [MaterialCircleAnimator new];

    [self.button addTarget:self action:@selector(buttonClick:event:)     forControlEvents:UIControlEventTouchUpInside];

}

#pragma mark - UINavigationControllerDelegate iOS7新增的2个方法
- (id) navigationController:(UINavigationController     *)navigationController animationControllerForOperation:    (UINavigationControllerOperation)operation fromViewController:    (UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    if (operation == UINavigationControllerOperationPush) {
        return self.circleAnimator;
    }else if (operation == UINavigationControllerOperationPop){
        return self.circleAnimator;
    }else{ // UINavigationControllerOperationNone
        return nil;
    }
}

- (IBAction) buttonClick:(id)sender event:(UIEvent *)event
{
    CGPoint position = [[[event allTouches] anyObject] locationInView:sender];

    ViewController2 *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewController2"];

    //convert to absolute position
    position = [self.button convertPoint:position toView:self.view];

    [self.circleAnimator setCenterPoint:position];
    [self.navigationController pushViewController:secondViewController animated:YES];

}

@end

这是我的 ViewController2.m:

#import "ViewController.h"
#import "ViewController2.h"

@implementation ViewController2

-(void)viewDidLoad
{
    self.navigationController.delegate = self;
    self.circleAnimator = [MaterialCircleAnimator new];
    [self.button addTarget:self action:@selector(clickBack:event:)     forControlEvents:UIControlEventTouchUpInside];
}

#pragma mark - UINavigationControllerDelegate iOS7新增的2个方法
- (id) navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    if (operation == UINavigationControllerOperationPush) {
        return self.circleAnimator;
    }else if (operation == UINavigationControllerOperationPop){
        return self.circleAnimator;
    }else{ // UINavigationControllerOperationNone
        return nil;
    }
}

- (IBAction)clickBack:(id)sender event:(UIEvent *)event
{
    CGPoint position = [[[event allTouches] anyObject] locationInView:sender];
    //convert to absolute position
    position = [self.button convertPoint:position toView:self.view];
    [self.circleAnimator setCenterPoint:position];

    [self.navigationController popViewControllerAnimated:YES];
}
@end

这是我在 Github 上的演示: https://github.com/TindleWei/MaterialCircleAnimation

您不想在 viewController 中每次点击按钮时都创建 viewController2 的新实例。您应该将其保留为 viewController 中的 属性 并仅在其 nil 时实例化它。所以 viewController 里面的 属性 secondViewController 的 getter 看起来像这样:

- (ViewController2 *)secondViewController {
  if (_secondViewController != nil) {
    return _secondViewController;
  }
  _secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewController2"];
  return _secondViewController;
}