2011-10-20 25 views
1

巨大で奇妙な問題: 写真を撮って、決めた名前で私のアプリに保存します(日+乱数)、私は " imagePath "NSString変数です。 このメソッドの最後まで、 "グローバル変数であるimagePath"の内容にアクセスできますが、別のメソッドで使用しようとすると、このアドレスをsqliteデータベースに保存してEXC_BAD_ACCESSを与えてください。 " "(、IMAGEPATH、また私は、%@のNSLog @");" との内容を参照しよう。それはcrashsを をいくつかのアイデアNSStringがアプリをクラッシュさせる可能性があります...

-(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; 
} 

答えて

2

問題は、これがあることです。これは、イベントループのサイクルの最後に発生する、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でそれを解放心配しないでください。 (ただし、複数回割り当てている場合は、割り当てる前に解放する必要があります)。アプリケーションが終了すると、メモリはOSによって再利用されます。

+0

素晴らしい!それは完璧だった!どうもありがとう。もう一つのこと:イメージの完全なパスを使ってイメージをUIImageに設定するにはどうしたらいいですか? (これは、/ Users/Sk *****/Library/Application Support/iPhone Simulator/4.3.2/Applications/15977219-DEFE-407A-BB80-72E188E18DD2/Documents/20-10-20111746を参照してください)。 png) – Oiproks

+0

あなたは別の質問でそれを尋ねるべきです。私はそれに答えることができますが、コメントセクションは場所ではありません。 :) –

-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; 
+1

このコードに括弧が多すぎます! (編集後でさえも) – Simon

1

あなたはこれを試すことが...

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

[imagePath retain]; 

// Your code// 

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

[imagePath release]; 
+1

deallocでの解放は同じ方法ではありません。 – Ishu

+0

この回答は間違っています。 OPは** imagePage **をインスタンス変数として保存していますので、他のメソッドでも使用できます。作成した直後にここでリリースすると、オブジェクトが割り当て解除され、ivarが破損した状態になる可能性があります。 @Ishu、このメソッドが複数回呼び出されている場合、** release **呼び出しをdeallocに残すと、メモリリークが発生する可能性があります。 –

+0

@craigそれでは、[imagePath release]; [imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@ "%@。png"、photoName]];のようになります。 [imagePath retain]; – Ishu

1

NSZombieEnabledMallocStackLogging、およびデバッガのguard malloc。そして、あなたのアプリケーションがクラッシュし、GDBコンソールで次のように入力します。

(gdb) info malloc-history 0x543216 

は、クラッシュの原因となったオブジェクトのアドレスで0x543216を交換し、あなたがはるかに便利なスタックトレースを取得し、それはあなたがピンポイントで役立つはずです問題の原因となっているコードの正確な行。

See this article for more detailed instructions.

0

あなたはIMAGEPATHに格納値は、あなたが所有していません。 stringByAppendingPathComponent:からオートレリースされたオブジェクトを取得しています。あなたはそれを保持しています。 (Btw:ios5で開発していますか?)

0

imagePathはグローバル変数です。クラスにはどこにでもアクセスできますが、その時間に値を保存すると、そのクラスを保持していないときに何が起こりますか?

値を取得したメソッドから離れると解放されます。それで、それを保持してください。

この行の後に

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

[imagePath retain]; 

、あなたが他の時間を保持して呼び出していない間にdeallocではないいずれかの方法でそれを解放。

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

自動解放オブジェクトにimagePathを割り当て:

関連する問題