0

我有一个问题,objc_msgSend 调用 NSScreen backingScaleFactor 函数,但是 objc_msgSend 通过 NSLog 返回 NSScreenAux 类型,NSScreen backingScaleFactor 应该在文档中返回 CGFloat 类型,有人有问题吗?

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

NSLog 打印“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. 两者userSpaceScaleFactorbackingScaleFactor都被记录为 return CGFloat。在 OS X 上,CGFloat是 atypedef用于float32 位double以下和 64 位以下,因此您必须使用%f来格式化 a CGFloat,而不是%@.

  4. 如果要发送返回 、 或 的消息,floatdouble必须long double使用objc_msgSend_fpretif 编译为 32 位,但objc_msgSendif 编译为 64 位。

  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 回答