应用程序因原因崩溃:集合< __ NSArrayM:0x7071700>在被列举时被突变

时间:2011-02-25 08:59:59

标签: iphone objective-c

你可以帮我找一下点击分段控件后我的应用程序崩溃的原因吗?不是总的来说,但经过一些点击后通常会这样做。

错误讯息:

 *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x7071700> was mutated while being enumerated.(
    "<PLImageTableSegment: 0x7051d30>",
    "<PLImageTableSegment: 0x7051d30>",
    "<PLImageTableSegment: 0x7051d30>",
    "<PLImageTableSegment: 0x7051d30>",
    "<PLImageTableSegment: 0x7051d30>",
    "<PLImageTableSegment: 0x7051d30>",
    "<PLImageTableSegment: 0x7051d30>",
    "<PLImageTableSegment: 0x7051d30>",
    "<PLImageTableSegment: 0x7051d30>",
    "<PLImageTableSegment: 0x7051d30>",
    "<PLImageTableSegment: 0x7051d30>",
    "<PLImageTableSegment: 0x7051d30>"
)'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00e51be9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x00fa65c2 objc_exception_throw + 47
    2   CoreFoundation                      0x00e516a9 __NSFastEnumerationMutationHandler + 377
    3   CoreFoundation                      0x00e4ae78 -[__NSArrayM dealloc] + 152
    4   PhotoLibrary                        0x0ac3a1c4 +[PLImageTable releaseSegmentCache] + 37
    5   PhotoLibrary                        0x0ac1898f -[PLPhotoLibrary dealloc] + 183
    6   CoreFoundation                      0x00d68a6c CFRelease + 92
    7   CoreFoundation                      0x00d8db8d _CFAutoreleasePoolPop + 237
    8   Foundation                          0x00018443 -[NSAutoreleasePool release] + 167
    9   UIKit                               0x002c9bf2 _UIApplicationHandleEvent + 8792
    10  GraphicsServices                    0x01787a36 PurpleEventCallback + 1550
    11  CoreFoundation                      0x00e33064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
    12  CoreFoundation                      0x00d936f7 __CFRunLoopDoSource1 + 215
    13  CoreFoundation                      0x00d90983 __CFRunLoopRun + 979
    14  CoreFoundation                      0x00d90240 CFRunLoopRunSpecific + 208
    15  CoreFoundation                      0x00d90161 CFRunLoopRunInMode + 97
    16  GraphicsServices                    0x01786268 GSEventRunModal + 217
    17  GraphicsServices                    0x0178632d GSEventRun + 115
    18  UIKit                               0x002cd42e UIApplicationMain + 1160
    19  Reportieris                         0x00001c60 main + 102
    20  Reportieris                         0x00001bf1 start + 53
)
terminate called after throwing an instance of 'NSException'

头文件:

#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>

@interface MainViewController : UIViewController <MFMailComposeViewControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate,UIActionSheetDelegate, UIScrollViewDelegate>{
    IBOutlet UITextField *virsraksts;
    IBOutlet UITextField *paraksts;
    IBOutlet UITextField *apraksts;
    IBOutlet UIPageControl *pageControl;
    UISegmentedControl *segControl;
    UIScrollView *horView;
    UIButton *nosutitButton;
    UIImage *im;
    NSMutableArray *bildes;
    NSMutableArray *bildesFileName;
}

@property (nonatomic, retain) UITextField *virsraksts;
@property (nonatomic, retain) UITextField *paraksts;
@property (nonatomic, retain) UITextField *apraksts;
@property (nonatomic, retain) IBOutlet UIButton *nosutitButton;
@property (nonatomic, retain) IBOutlet UIScrollView *horView;
@property (nonatomic, retain) IBOutlet UISegmentedControl *segControl;
@property (nonatomic, retain) IBOutlet UIPageControl *pageControl;
-(IBAction)textFieldDoneEditing:(id)sender;
- (IBAction)buttonPressed;
-(NSString *)dataFilePath;
-(void)applicationWillTerminate:(NSNotification *)notification;
- (IBAction)segControlClicked:(id)sender;

@end

实施档案:

#import "MainViewController.h"

@implementation MainViewController
@synthesize virsraksts;
@synthesize apraksts;
@synthesize paraksts;
@synthesize segControl;
@synthesize horView;
@synthesize nosutitButton;
@synthesize pageControl;

BOOL isCamera;
NSInteger nr;

-(NSString *)dataFilePath
{
    NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory=[paths objectAtIndex:0];
    return [documentsDirectory stringByAppendingPathComponent:@"data.plist"];
}

-(void)applicationWillTerminate:(NSNotification *)notification
{
    NSMutableArray *array=[[NSMutableArray alloc] init];
    [array addObject:paraksts.text];
    [array writeToFile:[self dataFilePath] atomically:YES];
    [array release];
}


-(IBAction)textFieldDoneEditing:(id)sender
{
    [sender resignFirstResponder];
}





// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]];
    horView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"horviewbg.png"]];
    horView.delegate = self;

    NSString *filePath=[self dataFilePath];
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) 
    {
        NSArray *array=[[NSArray alloc] initWithContentsOfFile:filePath];
        paraksts.text=[array objectAtIndex:0];
        [array release];
    }
    UIApplication *app=[UIApplication sharedApplication];
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(applicationWillTerminate:)
                                                 name:UIApplicationWillTerminateNotification
                                               object:app];


    bildes = [[NSMutableArray alloc] init];
    bildesFileName = [[NSMutableArray alloc] init];
    isCamera=NO;
    [horView setContentSize:CGSizeMake(0, 163)];

    UIImage *buttonImageNormal = [UIImage imageNamed:@"whiteButton.png"];
    UIImage *stretchableButtonImageNormal = [buttonImageNormal 
                                             stretchableImageWithLeftCapWidth:12 topCapHeight:0];
    [nosutitButton setBackgroundImage:stretchableButtonImageNormal 
                             forState:UIControlStateNormal];

    UIImage *buttonImagePressed = [UIImage imageNamed:@"blueButton.png"];
    UIImage *stretchableButtonImagePressed = [buttonImagePressed
                                              stretchableImageWithLeftCapWidth:12 topCapHeight:0];
    [nosutitButton setBackgroundImage:stretchableButtonImagePressed 
                             forState:UIControlStateHighlighted];

    if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) 
    {
        [segControl setEnabled:NO forSegmentAtIndex:0];
    }

    //deleting images   
    for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:NSTemporaryDirectory() error:NULL]) 
    {
        [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), file] error:NULL];
    }
    [super viewDidLoad];
}




- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    self.horView = nil;
    //deleting images

    for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:NSTemporaryDirectory() error:NULL]) 
    {
        [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), file] error:NULL];
    }
    [super viewDidUnload];
}


- (void)dealloc {
    [virsraksts release];
    [apraksts release];
    [paraksts release];
    [bildes release];
    [bildesFileName release];
    [segControl release];
    [pageControl release];
    [horView release];
    [nosutitButton release];
    [super dealloc];
}

-(void) showEmailModalView {

    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    picker.mailComposeDelegate = self; // &lt;- very important step if you want feedbacks on what the user did with your email sheet

    NSString *subject =[NSString stringWithFormat:@"Mobilais reportieris: %@",virsraksts.text];
    [picker setSubject:subject];

    // Set up recipients
    NSArray *toRecipients = [NSArray arrayWithObject:@"test@test.com"]; 


    [picker setToRecipients:toRecipients];

    // Attach an image to the email
    NSString *tempPath = NSTemporaryDirectory();
    for (int i=0;i<[bildesFileName count]; i++) 
    {
        NSString *imagePath = [tempPath stringByAppendingPathComponent:[bildesFileName objectAtIndex:i]];

        if ([[NSFileManager defaultManager] fileExistsAtPath:imagePath])
        {
            NSData *myData = [NSData dataWithContentsOfFile:imagePath];
            [picker addAttachmentData:myData mimeType:@"image/jpeg" fileName:[bildesFileName objectAtIndex:i]];
        }
    }

    // Fill out the email body text
    NSString *emailBody =[NSString stringWithFormat:@"%@<br />\n\n%@",apraksts.text,paraksts.text];
    [picker setMessageBody:emailBody isHTML:YES]; // depends. Mostly YES, unless you want to send it as plain text (boring)
    picker.navigationBar.barStyle = UIBarStyleBlack; // choose your style, unfortunately, Translucent colors behave quirky.
    [self presentModalViewController:picker animated:YES];
    [picker release];
}

- (IBAction)buttonPressed {
    [self showEmailModalView];   
}
#pragma mark -
#pragma mark MAIL DELEGATE

// Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the message field with the result of the operation.

- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{ 
    // Notifies users about errors associated with the interface
    switch (result)
    {
        case MFMailComposeResultCancelled:
            break;
        case MFMailComposeResultSaved:
            break;
        case MFMailComposeResultSent:
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"E-pasts" message:@"Veiksmīgi nosūtīts"
                                                           delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
            [alert show];
            [alert release];
        }
            break;
        case MFMailComposeResultFailed:
            break;

        default:
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"E-pasts" message:@"Neizdevās nosūtīt"
                                                           delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
            [alert show];
            [alert release];
        }

            break;
    }
    [self dismissModalViewControllerAnimated:YES];
}

#pragma mark -

- (IBAction)segControlClicked:(id)sender
{
    //int clickedSegment = [sender selectedSegment];
    UIImagePickerController *photoPicker =[[UIImagePickerController alloc] init];
    photoPicker.delegate = self;
    photoPicker.allowsEditing = NO;
    //NSLog(@"segmentAction: selected segment = %d", [sender selectedSegmentIndex]);
    if ([sender selectedSegmentIndex] == 0)
    {
        photoPicker.sourceType=UIImagePickerControllerSourceTypeCamera;
        isCamera=YES;
    }
    else {
        photoPicker.sourceType=UIImagePickerControllerSourceTypeSavedPhotosAlbum;;
        isCamera=NO;
    }

    [self presentModalViewController:photoPicker animated:YES];
    [photoPicker release];
}

#pragma mark  -


- (void)imagePickerController:(UIImagePickerController *)photoPicker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    if ([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:@"public.image"]) 
    {
        // you got an image

        UIImage * img = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
        if (isCamera==YES)
            UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
        NSString *tempPath = NSTemporaryDirectory();
        NSString *tempName=[[NSString alloc] initWithFormat:@"temp%d.jpg", [bildes count]];
        NSString *imagePath = [tempPath stringByAppendingPathComponent:tempName];
        [bildesFileName insertObject:tempName atIndex:[bildesFileName count]];
        [tempName release];


        NSData* imageData = UIImageJPEGRepresentation(img, 1.0);
        [imageData writeToFile:imagePath atomically:YES];
        [bildes insertObject:imageData atIndex:[bildes count]];

        [[photoPicker parentViewController] dismissModalViewControllerAnimated:YES];
        if(img!=nil)
        {

            horView.frame = CGRectMake(0, 140, 320, 163);
            [horView setContentSize:CGSizeMake((320*[bildes count]), 163)];

            //pievienojam bildi
            UIImageView *i=[[UIImageView alloc] initWithImage:[UIImage imageWithData:imageData]];
            [i setFrame:CGRectMake((320*[bildes count]-320+50),5,220,153)]; //Adjust X,Y,W,H as needed
            i.contentMode = UIViewContentModeScaleAspectFit;
            [horView addSubview:i];
            [i release];

            //pievienojam dzēšanas pogu
            UIButton *deleteButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; 
            [deleteButton setFrame:CGRectMake(320*[bildes count]-50,10, 28, 28)];
            [deleteButton setImage:[UIImage imageNamed:@"deletebutton.png"] forState:UIControlStateNormal];

            [deleteButton addTarget:self action:@selector(deleteImage:) forControlEvents:UIControlEventTouchUpInside];
            [deleteButton setTag:[bildes count]-1];
            [horView addSubview:deleteButton];
            [deleteButton release];


            //pabīdam bildi redzamajā rāmī
            [self performSelector:@selector(moveHorView) withObject:nil afterDelay:.5];
            pageControl.numberOfPages = [bildes count];  
            pageControl.currentPage = [bildes count];
        }
    //[imageData release];
    }
    else 
    {
        // movie!

        [[photoPicker parentViewController] dismissModalViewControllerAnimated:YES];
    }
}

-(void) deleteImage:(UIButton *)sender{
    //NSLog(@"yyy%d",sender.tag);
    nr=sender.tag;
    UIActionSheet *actionSheet = [[UIActionSheet alloc] 
                                  initWithTitle:@"Delete image?" 
                                  delegate:self 
                                  cancelButtonTitle:@"No"
                                  destructiveButtonTitle:@"Yep" 
                                  otherButtonTitles:nil];
    [actionSheet showInView:self.view];
    [actionSheet release];

}
-(void) moveHorView{
    [horView scrollRectToVisible:CGRectMake((320*[bildes count]-320),0,320,163) animated:YES];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)photoPicker {

    [photoPicker dismissModalViewControllerAnimated:YES];
}

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if (buttonIndex != [actionSheet cancelButtonIndex])
    {
        //deleting images from horView
        UIView* subview;
        while ((subview = [[horView subviews] lastObject]) != nil)
            [subview removeFromSuperview];

        //deleting image from tmp
        NSString *imagePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[bildesFileName objectAtIndex:nr]];
        if ([[NSFileManager defaultManager] fileExistsAtPath:imagePath])
        {
            [[NSFileManager defaultManager] removeItemAtPath:imagePath error:NULL];
        }

        //deleting image from arrays
        [bildes removeObjectAtIndex:nr];
        [bildesFileName removeObjectAtIndex:nr];


        //showing all images
        for (int i=0;i<[bildesFileName count]; i++) 
        {

            //adding image
            UIImageView *iw=[[UIImageView alloc] initWithImage:[UIImage imageWithData:[bildes objectAtIndex:i]]];
            [iw setFrame:CGRectMake((320*i)+50,5,220,153)]; //Adjust X,Y,W,H as needed
            iw.contentMode = UIViewContentModeScaleAspectFit;
            [horView addSubview:iw];
            [iw release];

            //adding delete button
            UIButton *deleteButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; 
            [deleteButton setFrame:CGRectMake(320*i+320-50,10, 28, 28)];
            [deleteButton setImage:[UIImage imageNamed:@"deletebutton.png"] forState:UIControlStateNormal];

            [deleteButton addTarget:self action:@selector(deleteImage:) forControlEvents:UIControlEventTouchUpInside];
            [deleteButton setTag:i];
            [horView addSubview:deleteButton];
            [deleteButton release];
        }
        [horView setContentSize:CGSizeMake((320*[bildes count]), 163)]; 
        [horView scrollRectToVisible:CGRectMake((320 * nr),0,320,163) animated:YES];
        pageControl.numberOfPages = [bildes count];  
        pageControl.currentPage = [bildes count];
    }
}


#pragma mark -
#pragma mark UIScrollViewDelegate methods

-(void)scrollViewDidScroll:(UIScrollView *)sv
{
    //showing pageControl.currentPage
    pageControl.currentPage = floor((sv.contentOffset.x - 160) / 320) + 1;

}

@end

我是iOS开发的新手,所以可能有一些内存泄漏。不知道什么是错的以及如何找到问题:/我试图评论一些功能,但没有什么真正帮助。

3 个答案:

答案 0 :(得分:1)

看起来问题出在UIImagePickerController上,并且仅在模拟器中(详见此处详细说明:http://blog.airsource.co.uk/index.php/2008/11/12/memory-usage-in-uiimagepickercontroller/)。在真实的设备上,一切都很好。

答案 1 :(得分:0)

已解决

我在coredata对象枚举中遇到同样的问题。

不要更改依赖于运行循环的ARRAY的子对象

喜欢==&gt;&gt;

如果我在循环中更改/修改对象,则会出现此错误。

 for (LoadList *objLL in ArrLoadList) {             // here Enumaration is Going on
        // here I removed objects in ArrLoadList and reassign the ArrLoadList .. 
        // it will give me this error 
        // So Don't change the Main Array object 
 }

答案 2 :(得分:-1)

我认为问题出在这些代码行中

for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:NSTemporaryDirectory() error:NULL]) 
{
    [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), file] error:NULL];
}

你在两个方法didLoad和didUnload中使用它。 你得到的原因是因为你正在更新以下数组的内容

[[NSFileManager defaultManager] contentsOfDirectoryAtPath:NSTemporaryDirectory() error:NULL]

当你进行彻底的枚举器课程时,你会明白“在使用枚举器时不更新内容”...... 因此,要克服这个问题,只需按照您使用此代码的所有地方进行操作....

NSArray* temp = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:NSTemporaryDirectory() error:NULL];
for (NSString *file in temp) 
{
    [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), file] error:NULL];
}

我希望这可以解决你的问题...