0

objc_msgSend が NSScreen backingScaleFactor 関数を呼び出すという問題がありますが、objc_msgSend は NSLog によって NSScreenAux タイプを返し、NSScreen backingScaleFactor はドキュメントで CGFloat タイプを返す必要があります。

NSScreen *screen = [NSScreen mainScreen];
NSLog(@"%@", objc_msgSend(screen, @selector(userSpaceScaleFactor))

NSLog print "NSScreenAux: 0x1661210"

新しい問題があります。objc_msgSend 関数を呼び出す

- (NSRect)convertRectToBacking:(NSRect)aRect NS_AVAILABLE_MAC(10_7);

コードは次のとおりです。

NSScreen* screen = [NSScreen mainScreen]; 
NSRect rect = NSMakeRect(0, 0, 100, 100); 
NSLog(@" %@ ", objc_msgSend(screen, @selector(convertRectToBacking:), rect));

アプリがクラッシュしました。どうすればよいですか?

4

1 に答える 1

3

いくつかの問題があります。

  1. を使用する準備ができていませんobjc_msgSend。フォーマット文字列で間違ったフォーマット指定子を使用しているという事実は危険信号です。

  2. あなたの質問テキストは言ってbackingScaleFactorいますが、あなたのコードは言っていますuserSpaceScaleFactor. あなたはどれが欲しいですか?

  3. userSpaceScaleFactorとの両方backingScaleFactorが を返すように文書化されていCGFloatます。OS X では、CGFloatは32 ビット未満および64 ビット未満typedef用であるため、ではなくを使用してフォーマットする必要があります。floatdouble%fCGFloat%@

  4. floatdouble、またはを返すメッセージを送信する場合は、32 ビット用にコンパイルする場合long doubleは使用する必要がありますが、64 ビット用にコンパイルする場合は使用する必要があります。objc_msgSend_fpretobjc_msgSend

  5. 呼び出すメソッドの型に常にキャストobjc_msgSend(または) する必要があります。objc_msgSend_fpret

したがって、これを 32 ビットで動作させるには:

NSScreen *screen = [NSScreen mainScreen];
NSLog(@"%f", ((CGFloat (*)(id, SEL))objc_msgSend_fpret)(screen, @selector(backingScaleFactor)));

64 ビットで動作させるには:

NSScreen *screen = [NSScreen mainScreen];
NSLog(@"%f", ((CGFloat (*)(id, SEL))objc_msgSend)(screen, @selector(backingScaleFactor)));
于 2012-11-20T06:39:23.713 に答える