NSString使我的应用程序崩溃......也许吧

时间:2011-10-20 12:04:48

标签: iphone objective-c nsstring nslog

巨大而奇怪的问题: 我拍照并用我决定的名字(日期+随机数)将它们保存在我的应用程序中,并将图片的地址存储在我的“imagePath”NSString变量中。 直到这个方法结束,我可以访问“imagePath,这是一个全局变量的内容;但是当我尝试在另一个方法中使用它时,我应该将此地址保存在sqlite数据库中,它给我EXC_BAD_ACCESS。 好吧,如果我尝试用“NSLog(@”%@“,imagePath)看到它的内容,”它崩溃了。 一些想法?

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];

    int r = arc4random() % 9999;
    NSDate *date = [NSDate date];
    NSString *photoName = [dateNameFormatter stringFromDate:date];
    photoName = [photoName stringByAppendingString:[NSString stringWithFormat:@"%d", r]];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@" %@.png", photoName]];

    UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage];

    // ----- CODE FOR SCALE THE IMAGE ----- //

    // ----- ----- - END CODE - ----- ----- //

    NSData *webData = UIImagePNGRepresentation(picture);
    CGImageRelease([picture CGImage]);
    [webData writeToFile:imagePath atomically:YES];
    NSLog(@"%@", imagePath);
    imgPicker = nil;
}

6 个答案:

答案 0 :(得分:2)

问题在于:

imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@" %@.png", photoName]];

imagePath分配给自动释放的对象。这意味着它将作为事件循环周期结束时发生的NSAutoreleasePool排放的一部分被释放。

由于你没有创建内存,但是你想让它闲置,你必须retain它:

[imagePath retain];

您需要确定的是,这段保留的记忆可以释放。由于我们并不确切知道您的应用是如何运作的,因此由您决定。如果你不止一次调用这个方法,你可能会想要释放它:

if (imagePath) {
    [imagePath release];
}
imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@" %@.png", photoName]];
[imagePath retain];

如果此对象只能在您的选择器控制器中存活,则应使用dealloc方法释放它:

- (void)dealloc {
    [imagePath release];
    // Other releases
    [super dealloc];
}

否则,如果这应该在您的应用程序的生命周期中存活,请不要担心在dealloc中释放它。 (但是如果你多次分配它,你仍然应该在分配它之前释放它。)当你的应用程序终止时,操作系统将回收内存。

答案 1 :(得分:1)

你可以试试这个......

imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@" %@.png", photoName]];

[imagePath retain];

// Your code//

[webData writeToFile:imagePath atomically:YES];
NSLog(@"%@", imagePath);

[imagePath release];

答案 2 :(得分:1)

在调试器中设置NSZombieEnabledMallocStackLoggingguard malloc。然后,当您的应用程序崩溃时,请在gdb控制台中输入:

(gdb) info malloc-history 0x543216

0x543216替换为导致崩溃的对象的地址,您将获得更有用的堆栈跟踪,它可以帮助您查明代码中导致问题的确切行。

See this article for more detailed instructions.

答案 3 :(得分:0)

您在imagePath中存储的值不归您所有。从stringByAppendingPathComponent:获取自动释放的对象。你保留了它。 (顺便说一句:你是在ios5下开发的吗?)

答案 4 :(得分:0)

因为imagePath是全局变量。那么你可以在课堂上的任何地方访问它,但是当你存储一些你没有保留它的值时会发生什么。

从它获得价值的方法离开后,它会释放。所以请使用保留它。

这一行之后

imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@" %@.png", photoName]];

[imagePath retain];

并且在你不打算保留任何其他时间时,不以任何方式释放它。

答案 5 :(得分:-1)

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
   NSString *imgPathWithOutDir = [[NSString alloc] initWithFormat:@" %@.png", photoName];
    imagePath = [documentsDirectory stringByAppendingPathComponent:imgPathWithOutDir];

    UIImage *picture = [info objectForKey:UIImagePickerControllerOriginalImage];

    // ----- CODE FOR SCALE THE IMAGE ----- //

    // ----- ----- - END CODE - ----- ----- //

    NSData *webData = UIImagePNGRepresentation(picture);
    CGImageRelease([picture CGImage]);
    [webData writeToFile:imagePath atomically:YES];
    NSLog(@"%@", imagePath);
    [imgPathWithOutDir release];
    imgPicker = nil;