推送ViewController会生成运行时异常

时间:2017-08-30 02:35:34

标签: ios objective-c exception runtimeexception

我有一个标签式应用程序。在故事板中,其中一个选项卡是导航控制器。在根视图中,弹出UIImagePickerController,以便用户可以拍摄或选择照片。

/*SnapItViewController.m*/
#import "SnapItViewController.h"
#import "FirstViewController.h"
#import "CollectionListViewController.h"
#import <sys/utsname.h>

@interface SnapItViewController ()

@end

@implementation SnapItViewController
@synthesize fetchedResultsController;
@synthesize currentLocation;

#pragma mark View lifecycle

- (void)awakeFromNib
{
    // Listen to takePicture notifications
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TakePicture) name:@"takePicture" object:nil];
    [super awakeFromNib];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    ipc = [[UIImagePickerController alloc] init];
    ipc.delegate = self;
    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
        ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
        [self presentViewController:ipc animated:YES completion:NULL];
    }else{
        ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        //launch image picker view controller
        [self presentViewController:ipc animated:YES completion:nil];
    }
    // Do any additional setup after loading the view.

}

- (void)viewWillAppear:(BOOL)animated {

   self.navigationController.navigationBarHidden = YES;

    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{    
    [super viewDidAppear:animated];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}
#pragma mark - ImagePickerController Delegate
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    UIImage* theImage = [info objectForKey:UIImagePickerControllerOriginalImage];

    if( picker.sourceType == UIImagePickerControllerSourceTypeCamera )
    {
        UIImageWriteToSavedPhotosAlbum(theImage, nil, nil, nil);
    }
    int height = -1;
    if([[NSUserDefaults standardUserDefaults] integerForKey:@"reduce_image"] == 0){
        height = 640;
    } else if ([[NSUserDefaults standardUserDefaults] integerForKey:@"reduce_image"] == 1) {
        height = 1024;
    } else {
        height = 1600;
    }

    UIImage* resizedImageForUpload = [UtilityFunctions scaleAndRotateImage:theImage maxResolution:height];
    NSData* imageDataForUpload = UIImageJPEGRepresentation(resizedImageForUpload, 1);   // reduced image! 

    NSString *userDataset = [UtilityFunctions retrieveFromUserDefaults:@"dataset"];

    [self didPickImage:imageDataForUpload atLocation:currentLocation
                     userDataset: userDataset];
    [picker dismissViewControllerAnimated:YES completion:nil];       
    [mLocationManager stopUpdatingLocation];     
    [self release];
    [self dismissViewControllerAnimated:YES completion:NULL];
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
        [picker dismissViewControllerAnimated:YES completion:nil];      
}

- (void)pushChildControllerForCollectedLeaf:(CollectedLeaf*)theCollectedLeaf imageToUpload:(NSData*)imageToUpload animated:(BOOL)animated
{
    CollectionDetailViewController* childController = [[[CollectionDetailViewController alloc]initWithNibName:@"CollectionDetailViewController" bundle:nil] autorelease];
    childController.collectedLeaf = theCollectedLeaf;

    //// Pass the image from image picker to Collection Detail View, and it'll handles the upload. ////
    //// Set to nil for existing collections. ////
    if (imageToUpload)
    {
        childController.imageToUpload = imageToUpload;
    }

    childController.hidesBottomBarWhenPushed = YES;
    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];

    [self.navigationController pushViewController:childController animated:animated];
}

- (void)pushChildControllerForCollectedLeaf:(CollectedLeaf*)theCollectedLeaf imageToUpload:(NSData*)imageToUpload
{
    [self pushChildControllerForCollectedLeaf:theCollectedLeaf imageToUpload:imageToUpload animated:YES];
}

#pragma mark Leaflet Photo Picker Delegate

- (void)didPickImage:(NSData*)imageData atLocation:(CLLocation*)cLocation userDataset:(NSString *)userDataset
{
    //// Creates a new Collected Leaf ////
    CollectedLeaf* collectedLeaf = (CollectedLeaf*)[NSEntityDescription insertNewObjectForEntityForName:@"CollectedLeaf" inManagedObjectContext:[self.fetchedResultsController managedObjectContext]];

    //// Stores the geo-location to mCollectedLeaf ////
    if (cLocation)
    {
        collectedLeaf.latitude = [NSString stringWithFormat:@"%f", cLocation.coordinate.latitude];
        collectedLeaf.longitude = [NSString stringWithFormat:@"%f", cLocation.coordinate.longitude];
        collectedLeaf.altitude = [NSString stringWithFormat:@"%f", cLocation.altitude];

    }
    else
    {
        collectedLeaf.latitude = kGeoLocationNotAvailable;
        collectedLeaf.longitude = kGeoLocationNotAvailable;
        collectedLeaf.altitude = kGeoLocationNotAvailable;
    }

    collectedLeaf.collectedDate = [NSDate date];
    collectedLeaf.selectedSpecies = kUnknownSpecies;
    collectedLeaf.userDataset = userDataset;

    [self pushChildControllerForCollectedLeaf:collectedLeaf imageToUpload:imageData animated:YES];
}

@end

用户选择照片后,会将CollectionDetailViewController推送到导航堆栈。在viewDidLoad的{​​{1}}方法中,它将CollectionDetailViewController推送到导航堆栈,导航堆栈显示UITable。

CollectionDetailDataViewController

当我点击UITable的一个单元格时,它会导致/*CollectionDetailViewController.m */ - (void)viewDidLoad { containerView.frame = [self largeFrame]; dataVC = [[CollectionDetailDataViewController alloc] init]; dataVC.delegate = self; dataVC.collectedLeaf = self.collectedLeaf; dataVC.view.frame = [self normalFrame]; [self.navigationController pushViewController:dataVC animated:NO]; [super viewDidLoad]; } 应用程序崩溃SpeciesViewController

Thread 1: exc_breakpoint (code=exc_i386_bpt subcode=0x0)

认为这是一个解除分配的问题,我试图评论所有涉及的dealloc方法,但问题仍然存在。我认为替换了pushviewcontroller将- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { RankedSpecies *theRankedSpecies = [fetchedResultsController objectAtIndexPath:indexPath]; SpeciesViewController* speciesController = [[[SpeciesViewController alloc]initWithNibName:@"SpeciesViewController" bundle:nil] autorelease]; speciesController.theSpecies = theRankedSpecies.Species; [[tableView cellForRowAtIndexPath:indexPath] setSelected:NO animated:YES]; [self.navigationController pushViewController:speciesController animated:YES]; } 添加为SpeciesViewController的子视图。

CollectionDetailDataViewController

现在转到下一个视图,然后应用程序崩溃并使用相同的异常代码。

我启用了Zombies并在断点导航器中添加了异常断点。我正在努力将我的代码版本添加到git中,以便其他人可以体验我的问题并可能确定解决方案。

打印在consol中的错误:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    RankedSpecies *theRankedSpecies = [fetchedResultsController objectAtIndexPath:indexPath];
    SpeciesViewController* speciesController = [[[SpeciesViewController alloc]initWithNibName:@"SpeciesViewController" bundle:nil] autorelease];
    speciesController.theSpecies = theRankedSpecies.Species;
    [[tableView cellForRowAtIndexPath:indexPath] setSelected:NO animated:YES];

    [self addChildViewController:speciesController];
    [self.view addSubview:speciesController.view];
    [speciesController didMoveToParentViewController:self];

}

崩溃堆栈跟踪: enter image description here

2 个答案:

答案 0 :(得分:0)

[picker dismissViewControllerAnimated:YES completion:nil];
[mLocationManager stopUpdatingLocation];
[self release];
[self dismissViewControllerAnimated:YES completion:NULL];

你同时解雇两个viewControllers?也许你可以尝试解除完成块中的第二个解雇。 self dismissViewControllerAnimated含糊不清,因为它可以关闭视图控制器或解除自我。我想你想要解雇自己,即SnapItViewController,所以你首先释放SnapItViewController,然后向它发送一个解雇信息,这显然是错误的。

您发布了SnapItViewController代码,但仍然没有发布您调用它的位置。

答案 1 :(得分:0)

解决方案最终被移除

[self release]

[self dismissViewControllerAnimated:YES completion:NULL];

来自SnapItViewController中的didFinishPickingMediaWithInfo