ошибка iOS 4? Файлы изображений, сохраненные в папке, перезаписываются после случайного количества сохраненных изображений - PullRequest
1 голос
/ 15 октября 2011

У меня есть приложение (SDK 4.3), которое сохраняет изображения в виде attachmemnts для путевой точки на карте Google. Сохранение файла является довольно стандартным (afaik) кодом UIImagePickerController. Вместо сохранения в рулон фотоаппарата я сохранял изображение, а затем уменьшенное изображение в подпапку. Я нуждаюсь в этом. В случайных, казалось бы, точках без ошибок, которые могут быть зафиксированы и зарегистрированы, изображения не будут сохраняться в папке, а вместо этого перезаписывают ранее сохраненные файлы изображений! Это выглядит для всего мира как FIFO-поп-музыка. Это серьезно странно, и я даже построил небольшое тестовое приложение и запустил его, как только появилось жуткость ... сохраняя серию изображений с камеры в одних и тех же папках, но получая тот же эффект. Изображения будут перезаписаны, когда будет достигнут случайный номер магического файла! Случайный в том смысле, что после 7 сохраненных изображений начинается перезапись ... даже после перезагрузки телефона, чтобы гарантировать утечку памяти, не проблема. Протрите приложение и попробуйте еще раз ... На этот раз это произойдет после сохранения 16 или 23 файлов изображений. Я пошел на все виды крайностей и не могу найти источник проблемы. В небольшом тестовом приложении тем же способом я сохраняю и в рулон камеры. Это сохранит там, но переписать в папке. Имена файлов состоят из 10 символов, случайным образом сгенерированных буквенно-цифровых символов.

Теперь я склонен понимать это как ошибку. Я всегда могу воспроизвести ошибку, но не предсказуемо. Возникает случайным образом.

Буду признателен за помощь, поскольку я вырываю свои волосы.

Вот код ...

   //tester.h

#import <UIKit/UIKit.h>

@interface tester : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
     UIImagePickerController *imgPicker;
    IBOutlet UIButton *pressit;
     IBOutlet UIButton *seeya;
    UIActivityIndicatorView *activity;
}
    @property (retain )UIImagePickerController *imgPicker;
    @property (nonatomic,retain)IBOutlet UIButton *pressit;
@property (nonatomic,retain)IBOutlet UIButton *seeya;
@property (nonatomic,retain)UIActivityIndicatorView *activity;
-(NSString *) genRandStringLength:(int) len ;
-(void)saveImagesFromPickerInTheBackgroundUsingImage:(UIImage *)img;
-(NSArray *)buildFilePaths;
- (IBAction)snapShots:(UIButton *)button;
-(IBAction)byebye:(id)sender;
@end

//=====================
//tester.m

#import "tester.h"
#import "MultiMediaUtilities.h"

@implementation tester

@synthesize imgPicker;
@synthesize pressit,seeya,activity;

//Image size constants
#define MAX_THUMBNAIL_RES_SIZE 103
#define MAX_IMAGE_RES_SIZE 640

- (IBAction)snapShots:(UIButton *)button
{
    if (!imgPicker) imgPicker = [[UIImagePickerController alloc]init];
    imgPicker.sourceType =  UIImagePickerControllerSourceTypeCamera;
    imgPicker.delegate = self;
    [self presentModalViewController:imgPicker animated:YES];   
}

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *memoImage = [[MultiMediaUtilities scaleAndRotateImage:[info objectForKey:@"UIImagePickerControllerOriginalImage"] toResolution:MAX_IMAGE_RES_SIZE ]retain];
    UIImageWriteToSavedPhotosAlbum(memoImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    [self saveImagesFromPickerInTheBackgroundUsingImage:memoImage]; 
    // Dismiss the camera
    [self dismissModalViewControllerAnimated:YES];
}


//builds paths to files in system with components
-(NSArray *)buildFilePaths
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *docsPath = [documentsDirectory stringByAppendingPathComponent:@"imagesfolder"];
    NSString *fullDocsPath = [docsPath stringByAppendingPathComponent:@"assets"];
    NSString *fullThumbsPath = [fullDocsPath stringByAppendingPathComponent:@"thumbs"];
    NSArray * retArray = [NSArray arrayWithObjects:fullDocsPath,fullThumbsPath,nil];
    return  retArray;
}


-(void)saveImagesFromPickerInTheBackgroundUsingImage:(UIImage *)img
{
    @try
    {
        NSFileManager *NSFm = [NSFileManager defaultManager];
        NSArray *pathsArray = [NSArray arrayWithArray:[self buildFilePaths]];
        NSString *fullDocsPath = [NSString stringWithFormat:@"%@", (NSString *)[pathsArray objectAtIndex:0]];
        NSString *fullThumbsPath = [NSString stringWithFormat:@"%@", (NSString *)[pathsArray objectAtIndex:1]];
        //Ensure Folders exist
        BOOL isDir=YES;
        NSError *error;
        if(![NSFm fileExistsAtPath:fullDocsPath isDirectory:&isDir])
            if(![NSFm  createDirectoryAtPath:fullDocsPath withIntermediateDirectories:YES attributes:nil error:&error])
                NSLog(@"Error: Create Images folder failed");

        //create thumbs folder too
        if(![NSFm fileExistsAtPath:fullThumbsPath isDirectory:&isDir])
            if(![NSFm  createDirectoryAtPath:fullThumbsPath withIntermediateDirectories:YES attributes:nil error:&error])
                NSLog(@"Error: Create Thumbs folder failed");
        //build the filenames & paths
        NSString *newImageName= [NSString stringWithFormat:@"%@.png", [self genRandStringLength:10]];
        NSString *imagePath = [[fullDocsPath stringByAppendingPathComponent:newImageName]retain];
        NSLog(@"SavingIMage ImagePath = %@",imagePath);

        NSString *thumbPath =  [[fullThumbsPath stringByAppendingPathComponent:newImageName]retain];
        NSLog(@"SavingIMage thumbPAth = %@",thumbPath);

        //Write the files out
        NSData *imgData = UIImagePNGRepresentation(img);
        [imgData writeToFile:imagePath options:NSDataWritingAtomic error:&error];
        if (!error) {
            NSLog(@"Error writing image %@",error.description);
        }
        NSData *thumbData = UIImagePNGRepresentation(img);
        [thumbData writeToFile:thumbPath options:NSDataWritingAtomic error:&error];
        if (!error) {
            NSLog(@"Error writing thumb %@",error.description);
        }
    }
    @catch (NSException * e) 
    {
        NSLog(@"Exception: %@", e);
    } 
}

-(NSString *) genRandStringLength:(int) len 
{
    NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    NSMutableString *randomString = [NSMutableString stringWithCapacity: len];
    for (int i=0; i<len; i++) 
    {
        [randomString appendFormat: @"%c", [letters characterAtIndex: rand()%[letters length]]];
    }
    return randomString;
}

- (void)image:(UIImage*)image didFinishSavingWithError:(NSError *)error contextInfo:(NSDictionary*)info {
    NSString *message;
    NSString *title;
    if (!error)
    {
        title = @"Camera...";
        message = @"Image saved!...Just as well.";
    }
    else
    {
        title = @"Error";
        message = [error description];
    }
    UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle:title
                          message:message 
                          delegate:self
                          cancelButtonTitle:@"OK"
                          otherButtonTitles:nil];
    [alert show];
    [alert release];
    if (image !=NULL){
        [image release];
        image=nil;
    }
    if(info !=NULL)
    {
        [info release];
        info=nil;
    }
}
- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

-(void)dealloc
{
    [imgPicker release];
    [pressit release];
    [seeya release];
    [activity release];
    [super dealloc];
}
@end

Ответы [ 2 ]

3 голосов
/ 15 октября 2011

Даже с семенами, это неуместное использование случайных чисел.

Три подхода:

  1. Использовать увеличенный порядковый номер.(1, 2, 3 и т. Д.)
  2. Использовать UUID из [[NSProcessInfo processInfo] globallyUniqueString]
  3. Использовать имя файла, составленное из даты и времени.
0 голосов
/ 15 октября 2011

Как сказал Матс, если вы не инициализируете генератор случайных чисел с помощью srand, rand () будет вести себя странно и не ожидать, что он сгенерирует случайные числа. Это может привести к тем же именам файлов, что и у вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...