iOS SDK は 64 ビットをサポートしているため、ほとんどのコードは直接変換してコンパイルすることができますが、これらのコードは実行時に差異が生じる可能性があるため、開発時には特に注意が必要です。Cocoa-Charts は開発中にこのような問題を発見しました。
問題の現象:
CoreGraph の描画メソッドと NSString の drawInRect メソッドは、64 ビット環境では競合が発生します。64 ビット環境では、drawInRect を呼び出した後、CGContext のパスがクリアされ、CGContextStrokePath が何の描画操作も行わなくなりますが、32 ビット環境では問題ありません。
問題のコード:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 0.5f);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
// コード省略
// コントロール内に直線を描画
CGContextMoveToPoint(context, 0.f, 0.f);
CGContextAddLineToPoint(context, 100.f, 100.f);
// 指定されたテキストをコントロール内に表示
NSString string = @"TEST";
[string drawInRect(0, 0, 100, 20)
withFont: [UIFont systemFontOfSize:14.f]
lineBreakMode
alignment];
// コード省略
CGContextStrokePath(context);
CGContextFillPath(context);
解決策:
コードを分割し、CoreGraph の描画メソッドを使用するコードセグメントと NSString の drawInRect メソッドを呼び出すコードセグメントを別々に記述します。
修正後のコード:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 0.5f);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
// コード省略
// コントロール内に直線を描画
CGContextMoveToPoint(context, 0.f, 0.f);
CGContextAddLineToPoint(context, 100.f, 100.f);
// コード省略
CGContextStrokePath(context);
CGContextFillPath(context);
// 指定されたテキストをコントロール内に表示
NSString string = @"TEST";
[string drawInRect(0, 0, 100, 20)
withFont: [UIFont systemFontOfSize:14.f]
lineBreakMode
alignment];
最後に、バグの発見者に感謝します:
Marco Almeida(http://www.marcoios.com/MarcoiOS/index.html)