【问题标题】:Failed to use CGPoint, the struct, in Swift未能在 Swift 中使用结构体 CGPoint
【发布时间】:2015-06-09 14:16:27
【问题描述】:

我的情况:

我学习 Swift 有一段时间了,Swift 是我为 iOS 开发学习的唯一语言,这意味着我没有系统地学习 Objective-C。我可以稍微阅读一下OC Code。

当我尝试将 OC 项目转换为 Swift 项目时,遇到了CGPoint 问题。

Objective-C 代码:

- (void)drawFramesetter:(CTFramesetterRef)framesetter
   attributedString:(NSAttributedString *)attributedString
          textRange:(CFRange)textRange
             inRect:(CGRect)rect
            context:(CGContextRef)c
{
           .
           .

CTFrameRef frame = CTFramesetterCreateFrame(framesetter, textRange, path, NULL);
CFArrayRef lines = CTFrameGetLines(frame);
NSInteger numberOfLines = CFArrayGetCount(lines);
CGPoint lineOrigins[numberOfLines];  // *** The place I had been obstructed! ***

           .
           .
           .
}

我的问题:

  • 我不知道为什么声明为CGPoint lineOrigins[numberOfLines]的这行代码没有*来创建实例变量lineOrigins

    我未经证实的猜测是CGPoint 是一个结构而不是Class,但对我来说创建一个没有*= 的实例变量仍然很神秘。

  • 让我感到困惑的另一点是[numberOfLines][numberOfLine] 是一个数组吗?

  • 请教我如何将CGPoint lineOrigins[numberOfLines]; 翻译成 Swift 或给我一些提示。


非常感谢您的指导和时间。

伊桑·乔

【问题讨论】:

    标签: swift cgpoint


    【解决方案1】:

    线

    CGPoint lineOrigins[numberOfLines];
    

    创建一个 C CGPoint 对象数组。

    它写在一个函数内部,所以它创建了一个本地(堆栈)变量。 只有当numberOfLines 是编译时常量时,该代码才会编译,因为编译器必须在编译时为堆栈上的数组分配固定数量的空间。

    C 结构是简单的“模板”,将一块内存解释为包含一个或多个标量值。这些值按顺序存储在内存中。

    C 数组也是一种将内存块视为一个或多个标量“事物”的序列序列的方式。这些标量可以是简单的标量,比如整数,也可以是结构体。

    当您在示例中定义 C 数组时,编译器会为整个数组腾出内存空间,并将变量设置为指向第一个元素的指针。

    lineOrigins 的类型实际上是“指向 CGPoint 的指针”类型。在 C 中,数组类型和指向该类型对象的指针是可互换的。它有点像 Swift 的不安全缓冲区指针。没有范围检查。

    编辑:

    类似的 Swift 声明是:

    var lineOrigins = [CGPoint]()
    

    或者,用一堆零点预先填充它:

    var lineOrigins = [CGPoint](count: numberOfLines, repeatedValue: CGPointZero)
    

    【讨论】:

    • 感谢您的具体回答。那么,那行代码就是一个数组,里面还有一些 CGPoint 类型的对象,对吧?理解了那行代码的逻辑,我想我可以写出正确的代码了。
    • 在 Swift 中,我写了这样的代码,var lineOrigins = [numberOfLines] as [CGPoint],我仍然有疑问如何将NSInteger转换为CGPoint
    • 您不会将 NSInteger 转换为 CGPoint。这些就像油和水。不相关且不可兑换。您报告的错误消息可能是错误的错误消息。 Swift 经常这样做。
    • 好的,拜托,你能教一下如何用 Swift 表达正确的逻辑吗?我已经被那些语法问题弄糊涂了……
    • 非常感谢,这将帮助我理解这个概念。
    【解决方案2】:

    CGPoint 是一个 C 结构体,应该翻译成一个 C 结构体。

    CGPoint lineOrigins [...] 是一个名为 lineOrigins 的局部变量,它是一个 struct CGPoint 的数组。

    CGPoint lineOrigins [numberOfLines] 是一个名为 lineOrigins 的局部变量,它是一个包含 numberOfLines 个元素的 struct CGPoint 数组。

    有一个数组初始化方法,您可以在其中传递数组元素的数量,以及一个重复的数组元素。

    【讨论】:

    • 感谢您的回答。正如您提到的,CGPoint lineOrigins[...] 是一个 CGPoint 数组。但是lineOrigins的类型是NSInteger,那怎么可能把NSInteger转换成CGPoint呢?你能说出这个 C 结构在 Swift 中的具体语法吗?
    • 其实CGPoint lineOrigins [numberOfLines]定义了一个固定大小的CGPoint结构的C数组,而不是数组对象。那是与 NSArray 不同的动物(NSArray 是 Swift 数组的近亲。C 数组有很大不同。)
    • lineOrigins 的类型是“指向 CGPoint 的指针”。在 C 中,数组类型和指向该类型对象的指针是可以互换的。
    • Swift 能够创建包含 Int 或 Structs 等值的 Array 对象。 C/Objective-C 不能做到这一点。标量类型和对象类型之间的区别在 Swift 中是模糊的,但在 C/Objective-C 中非常严格
    猜你喜欢
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    相关资源
    最近更新 更多