2

メモリ不足警告クラッシュに関する多くの投稿を読みましたが、アプリでクラッシュの問題を解決できませんでした。機器の割り当ては、2 ~ 7MB の範囲のライブ バイトを示しています。7 または 7.5 MB を超えて急増することはありませんが、それでもアプリがクラッシュします。

割り当てとアクティビティモニターがメモリ使用量の異なる値を示していることを伝えるいくつかのリンクを読みました。前述のように、割り当てには最大 7 ~ 7.5 MB が表示されますが、アクティビティ モニターでは、アプリの起動時に約 75 MB の使用量が表示され、プログラムを使用すると、使用量が増減し始めます。最大で 110 ~ 120MB になり、その後 75 ~ 80MB に減少します。

VM トラッカーでダーティ サイズと常駐サイズを確認するように指示されているリンクもあります。VM Tracker をチェックインすると、Dirty サイズは 30MB から始まり、アプリを使用するにつれて増加し始めます。400MBを超えています。私は約 150 枚の画像を使用しており、そのうち約 70 ~ 80 枚は 1024x1024 サイズ、約 35 枚は 110x110 サイズ、残りは 3000x4000 サイズの画像です。これらの画像はすべて元々 png 形式でしたが、プログラムで JPG+ALPHA に変換し、アセットとしてアプリケーションに追加しました。対応する画像をロードする必要があるときはいつでも、JPG+ALPHA 画像を 16 の部分に分割し、最終的にそれらを結合して元の画像を取得します。解像度 3000x4000 の画像を読み込もうとしたときに、割り当てでメモリが 40 ~ 45MB まで急増したため、この方法を使用しました。この方法により、メモリが 10MB を超えないようにします。

これらの記録と統計はすべて、シミュレーターを使用して測定されます。

アプリケーションはシミュレーターではクラッシュしませんが、実際のデバイスではクラッシュします。テストにはiPad2を使用しています。

この問題を解決するのを手伝ってください。私は過去 2 日間立ち往生しており、アプリのクラッシュを見て完全にイライラしています。

4

2 に答える 2

0

読み込もうとしている画像が非常に大きいです。おそらく、CATiledLayer を使用して画像を表示することを検討する必要があります。Apple クラスの定義はこちらにあります

また、画像のレンダリングを容易にすることと、画像のメモリ使用量を削減することの違いも考慮してください。画像を小さな断片に分割すると、個々の描画負荷が軽減されますが、それらの画像のそれぞれがメモリに読み込まれると、メモリの問題が発生します。

タイル レイヤーは、可視タイルのみを読み込もうとすることでメモリ使用量を抑えながら、非常に大きな画像を表示します。

また、シミュレータには、実際のデバイスのメモリ制限はありません。実際のデバイスですべてのストレス テストを実行する必要があります。

編集: UIImage imageNamed は画像をキャッシュし、メモリの問題をさらに悪化させる可能性があるため、使用を控える必要があります。代わりに imageWithContentsOfFile を使用してください。

于 2012-07-25T05:04:38.153 に答える
0

このコードは正しいですか?

    UIImageView* framebadgeOrAccessoryImage = [[UIImageView alloc]initWithFrame:sizeOfFrameOrAccessoriesView];
    [framebadgeOrAccessoryImage setCenter:imageArea.center];
    [framebadgeOrAccessoryImage setContentMode:UIViewContentModeScaleAspectFit];
    [framebadgeOrAccessoryImage setImage:badgeOrAccessoryImage];
    [framebadgeOrAccessoryImage setTag:iObjectTag];
    [framebadgeOrAccessoryImage setObservationInfo:@"BadgeAccessories"];
    [framebadgeOrAccessoryImage setExclusiveTouch:YES];

    iObjectTag++;

    [framebadgeOrAccessoryImage setMultipleTouchEnabled:YES];
    [framebadgeOrAccessoryImage setBackgroundColor:[UIColor clearColor]];
    [framebadgeOrAccessoryImage setUserInteractionEnabled:YES];

    [imageArea addSubview:framebadgeOrAccessoryImage];

selectedItem = framebadgeOrAccessoryImage;

    [framebadgeOrAccessoryImage release];

設定したタグを使用して、他のメソッドで「framebadgeOrAccessoryImage」を使用しています。コードの最後の行で行ったように「framebadgeOrAccessoryImage」をリリースするか、リリース後に nil に割り当てる必要がありますか?

ここでは「framebadgeOrAccessoryImage」が「selectedItem」という名前で使用されています。

- (void)panRecognized:(UIPanGestureRecognizer *)gestureRecognizer
{   
    if(selectedItem.image && [gestureRecognizer isEnabled])
    {
        UIImageView *piece = selectedItem;

        if ((([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged)) && [((NSString*) [piece observationInfo]) isEqualToString:@"BadgeAccessories"])
        {
            CGPoint translation = [gestureRecognizer translationInView:[piece superview]];
            [piece setCenter:CGPointMake([piece center].x + translation.x, [piece center].y + translation.y)];
            [gestureRecognizer setTranslation:CGPointZero inView:[piece superview]];

        }

        if ([gestureRecognizer state] == UIGestureRecognizerStateEnded ||[gestureRecognizer state] == UIGestureRecognizerStateCancelled || [gestureRecognizer state] == UIGestureRecognizerStateFailed)
        {   
            if(CGRectContainsPoint([[self view]viewWithTag:RECYCLEBIN_TAG].frame, [gestureRecognizer locationInView:imageArea]))
            {
                NSAutoreleasePool* pool = [[NSAutoreleasePool alloc]init];
                [objectsAdded removeObjectForKey:[NSString stringWithFormat:@"%d",selectedItem.tag]];
                [pool release];
                [UIView beginAnimations:NULL context:nil];
                [UIView setAnimationBeginsFromCurrentState:YES];
                [UIView setAnimationDuration:0.4];
                [UIView setAnimationDidStopSelector:@selector(propDeleted:finished:context:)];
                [UIView setAnimationDelegate:self];

                [selectedItem setFrame:CGRectMake(selectedItem.frame.origin.x, selectedItem.frame.origin.y, 5, 5)];
                selectedItem.center = [[[self view]viewWithTag:RECYCLEBIN_TAG]center];
                [UIView commitAnimations];
            }
            else
            {
                [self applyEffectOnTouch:0];
            }
        }
    }
}
于 2012-07-24T13:27:50.090 に答える