开发者

App crashes with reason: Collection <__NSArrayM: 0x7071700> was mutated while being enumerated

开发者 https://www.devze.com 2023-02-13 14:18 出处:网络
Can you please help me to find reason why my app crashes after clicking on segmented control? Not allways, but usualy after someclicks.

Can you please help me to find reason why my app crashes after clicking on segmented control? Not allways, but usualy after some clicks.

Error message:

 *** 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'

header file:

#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

implementation file:

#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 r开发者_JAVA百科elease];


        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

I'm new to iOS developing, so maybe there is some memory leak. Don't have an idea whats wrong and how to locate problem :/ I tried to comment out some functions, but nothing really helped.


Looks like the problem was with UIImagePickerController and only in simulator (more described in details here: http://blog.airsource.co.uk/index.php/2008/11/12/memory-usage-in-uiimagepickercontroller/ ). On real device everything works quite fine.


solved

I had same problem in coredata objects enumeration.

Do not change sub object which relies in ARRAY on which Loop is Running

Like ==>>

If I change/Modify object while in loop, it will give this error.

 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 
 }


I think the problem is in these line of code

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

and you are using it in two methods didLoad and didUnload. The reason that you are getting because you are updating the content of the following array

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

When you go thorough enumerator class you will get this caution of "not updating the content while enumerator is in use" ... So to overcome this problem simply do following to all the places where you have used this code....

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

i hope this would solve your problem...

0

精彩评论

暂无评论...
验证码 换一张
取 消