1

customClass の drawRect メソッドで描画するアプリケーションを開発しています。

ビューのグラフィック コンテキストで線を描画します。setNeedsDisplay を使用して何度も再描画すると、メモリ警告が表示され、アプリがすぐにクラッシュします。

drawRect コードにリークがないかどうかを確認しました。何も見つかりませんでした。メモリ割り当ても大きな違いはありませんでした。

問題は一度修正され、iOS デバイスが再起動されました。しかし、私はクラッシュが再び繰り返されると確信しています。何が問題になる可能性があります。同様の問題に直面した人はいますか?

コードは以下のとおりです。

- (void)drawRect:(CGRect)rect{

[self drawTheTimeLineHorizontally];
}
- (void) drawTheTimeLineHorizontally {


    //Get the current graphics context
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    CGContextSaveGState(currentContext);

    [UIColorFromRGB(kCalendarTimeLineColor) setStroke];

    CGContextSetLineWidth(currentContext, 1);

    CGMutablePathRef path = CGPathCreateMutable();

    NSArray *hours = [self currentZoomLevelIntervalList];

    int numHours = [hours count];

    for (int i = 0; i < numHours; ++i) {



        CGPathMoveToPoint(path, NULL, 0, (i+kMultiplierTopDailyCalendarTimeline)*offset+2);
        [self drawHoursLeftOfLines:[hours objectAtIndex:i] withContext:currentContext withRect:CGRectMake(kOriginXOfTextInTimeLine, (i+kMultiplierTopDailyCalendarTimeline)*offset+(offset/3), kWidthOfTextInTimeLine, offset/3)];

        [UIColorFromRGB(kCalendarTimeLineColor) setStroke];
        CGPathAddLineToPoint(path, NULL, widthOfDailyCalendar+orginXEventTile, ((i+kMultiplierTopDailyCalendarTimeline)*offset+2));


    }

    CGPathMoveToPoint(path, NULL, 0, (numHours+kMultiplierTopDailyCalendarTimeline)*offset+2);
    CGPathAddLineToPoint(path, NULL, widthOfDailyCalendar+orginXEventTile, (numHours+kMultiplierTopDailyCalendarTimeline)*offset+2);


    CGContextAddPath(currentContext, path);

    CGContextDrawPath(currentContext, kCGPathStroke);
    //CGContextClosePath(currentContext);
    CGPathRelease(path);

    //Restore the saved context
    CGContextRestoreGState(currentContext);


}


- (void) drawHoursLeftOfLines:(NSString*) time withContext:(CGContextRef) context withRect:(CGRect) contextRect {

    [UIColorFromRGB(kTimeLineHourTextColor) setStroke];
    CGContextSelectFont(context,  kTimeLineHourTextFontStyle , kFontSizeTimeLineText, kCGEncodingMacRoman);
    CGContextSetCharacterSpacing (context, 1);
    CGContextSetTextDrawingMode(context, kCGTextFillStroke);

    CGAffineTransform xform = CGAffineTransformMake(
                                                    1.0,  0.0,
                                                    0.0, -1.0,
                                                    0.0,  0.0);
    CGContextSetTextMatrix(context, xform);

    CGContextShowTextAtPoint(context, contextRect.origin.x, contextRect.origin.y, [time cStringUsingEncoding:NSASCIIStringEncoding], [time length]);
}

アップデート:

再び同じ流れでクラッシュが繰り返されました。これは、デバイスを再起動してから 8 時間以上経過した後に発生しました。アプリを 8 時間も使用していません。デバイスを再起動した後、アプリケーションはその特定のフローでまったくクラッシュしません。

4

1 に答える 1

1

1) メソッド名getCurrentZoomLevelIntervalListを修正します。おそらく「currentZoomLevelIntervalList」だけです。他の開発者と ARC に混乱を引き起こしました。

2) アナライザーを実行し、すべての警告を修正します。

3) 計測器を使用して、保持されているがリークされていないメモリによるメモリ損失をチェックします。後者は、まだポイントされている未使用のメモリです。Instruments の Allocations Instrument で Heapshot を使用します。

Heapshot を使用してメモリ クリープを検出する方法については、bbum ブログを参照してください。

基本的には、Instruments 割り当てツールを実行し、ヒープショットを取得し、コードの直感を実行して、別のヒープショットを 3 ~ 4 回繰り返す方法があります。これは、反復中に割り当てられ、解放されないメモリを示します。

結果を把握するには、個々の割り当てを確認してください。

オブジェクトの保持、解放、および自動解放が発生する場所を確認する必要がある場合は、インストゥルメントを使用します。

計測器で実行し、割り当てで「参照カウントの記録」をオンに設定します (オプションを設定するには、記録を停止する必要があります)。ピッカーを実行し、記録を停止し、そこで ivar (datePickerView) を検索し、ドリルダウンすると、すべての保持、解放、および自動解放が発生した場所を確認できます。

于 2012-02-01T11:28:13.190 に答える