【问题标题】:-sizeWithFont Functions Differently on Device-sizeWithFont 在设备上的功能不同
【发布时间】:2011-02-07 14:47:26
【问题描述】:

因此,在使用NSString-sizeWithFont 系列方法调用时,我似乎遇到了一些奇怪的行为,具体取决于我是在iPhone 模拟器还是实际设备上调用它。

很简单,当-sizeWithFont:constrainedToSize:lineBreakMode:方法调用的接收者是nil时,返回给模拟器的CGSize就是{0, 0}但是,在设备上,返回结果与我在方法调用中指定的constrainedToSize:参数相同的CGSize值。请参阅以下日志语句:

模拟器:

someString: (null)
someStringSize: {0, 0}

设备:

someString: (null)
someStringSize: {185, 3.40282e+38}

模拟器上的行为是我所期望的。并不是说这个问题很难规避,而是 1)我有点困惑,为什么这一系列函数在模拟器和实际设备上的行为会有所不同,以及 2)为什么在 nil 接收器上调用方法会返回一个特定的、确定性的结果?

感谢你们提供的任何指示或见解!

编辑:我想我应该提到我正在针对 3.1 SDK 构建。

【问题讨论】:

    标签: iphone layout fonts nsstring null


    【解决方案1】:

    Apple 关于Sending messages to nil 的文档对此进行了解释:

    从消息返回到 nil 的值也可能是有效的:

    • 如果方法返回一个对象,那么发送给 nil 的消息返回 0 (nil) ...
    • 如果方法返回任何指针类型、任何大小小于或等于 sizeof(void*) 的整数标量、float、double、long double 或 long long,则发送到 nil 的消息返回 0 .
    • 如果该方法返回一个结构,如Mac OS X ABI Function Call Guide 所定义的要在寄存器中返回,则发送到 nil 的消息将为数据结构中的每个字段返回 0.0。其他结构数据类型不会用零填充。
    • 如果该方法返回上述值类型以外的任何值,则发送到 nil 的消息的返回值是未定义的。

    虽然本文档没有专门讨论 iPhone(而且它是在 iPhone SDK 发布之前编写的),但请注意第三和第四点:如果方法返回结构体(例如 CGSize),则行为是平台相关的。只有在 CPU 寄存器中返回的值才用零填充。我不是 iPhone 的 ARM 架构方面的专家,但很可能在 iPhone 上,sizeWithFont: 的返回值不会在寄存器中返回,而不是 i386。在这种情况下,在模拟器上运行时返回的结构将被填充为零,而在 iPhone 上运行时该值将是未定义的。

    【讨论】:

    • 是的,我记得在 Apple 的文档中读过有关向 nil 发送消息的信息。但是,设备上的案例的有趣之处在于,返回的结果 is 已定义:它始终是我传递给-sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: 的边界矩形的大小
    • 对不起。我实际调用的方法是-sizeWithFont:constrainedToSize:lineBreakMode:。在nil上调用此方法在设备上的返回结果与我作为constrainedToSize:参数传递的CGSize相同。
    • 正如我所说,我只是推测,但我的直觉是,在 ARM 架构上,方法的返回值通常与 constrainedToSize: 参数放在相同的内存位置/相同的寄存器中.
    • 明白了。嗯,这对我来说听起来很合理。感谢您的洞察力。
    • 那么我该如何解决这个问题?当我不传递它时它会返回不同的值nil 也...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-26
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多