类型识别问题在将OC转换为Swift的过程中

时间:2015-06-05 06:37:20

标签: objective-c swift

我的情况:

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

当我尝试将OC项目翻译成Swift项目时,我遇到了Type Recognition问题。

Objective-C代码:

static inline NSRegularExpression * AccountRegularExpression() {
static NSRegularExpression *_accountRegularExpression = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    _accountRegularExpression = [[NSRegularExpression alloc] initWithPattern:AccountRegular options:NSRegularExpressionCaseInsensitive error:nil];
});

return _accountRegularExpression;
}

我对那些神秘的代码感到困惑。

我的问题:

  • 现在,我刚刚在swift和OC中遇到了两个不同的东西,几乎是variable instancefunction,这意味着我可以读取和编写代码来初始化变量实例和crate功能。但是我从来没有在OC中看到类似的东西(是的,我是初学者......),它看起来不像变量实例或方法。

  • 在此问到这个问题之前,我试着编写一个swift函数作为原始函数。问题是,在我构建项目之后,编译器没有抛出任何错误。

这是我的Swift代码:

func AccountRegularExpression() -> NSRegularExpression {
    var accountRegularExpression: NSRegularExpression!
    var onceToken: dispatch_once_t = 0
    dispatch_once(&onceToken, {
        accountRegularExpression = NSRegularExpression(pattern: self.AccountRegular, options: NSRegularExpressionOptions.CaseInsensitive, error: nil)
    })
    return accountRegularExpression
}
  • 我不知道这个Swift代码是否具有与OC代码相同的功能。

我的问题:

  • 你能告诉我OC代码是一个变量实例吗?我认为这不是一种功能或方法。

  • 我谷歌关键词inline,这是反编译的过程。这个过程在Swift中仍然有效吗?

  • 如何以正确的方式在Swift中翻译OC代码,我想我的swift代码不正确。


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

Ethan Joe

3 个答案:

答案 0 :(得分:1)

转换是错误的,因为变量_accountRegularExpressiononceToken在C中声明为static,对于局部变量意味着它的状态保持在函数调用之间,整个生命周期都是该程序,类似于全局变量。

它们是static对于此函数的正确运行至关重要,即返回单例实例。如果它们不是static,那么:

  • dispatch_once要求您为其指定一个“存储在全局或静态范围内”的dispatch_once。通过为其提供具有自动存储的局部变量,您将调用未定义的行为。不可能知道它是否会执行一次或多次。
  • 如果_accountRegularExpression不是static,则表示此函数无法记住并返回之前创建的相同实例。因此,它不是“单身人士”。如果dispatch_once仅执行一次,那么在第二次及以后的时间,此函数将返回nil。如果dispatch_once执行多次,那么每次再次执行时,它将返回一个新的独立实例。在任何情况下都不会返回之前返回的实例。

为了使它在Swift中正常运行,一种方法是使这些变量成为全局变量:

var accountRegularExpression: NSRegularExpression!
var onceToken: dispatch_once_t = 0
func AccountRegularExpression() -> NSRegularExpression {
    dispatch_once(&onceToken, {
        accountRegularExpression = NSRegularExpression(pattern: self.AccountRegular, options: NSRegularExpressionOptions.CaseInsensitive, error: nil)
    })
    return accountRegularExpression
}

然而,函数在Swift中返回单例的更好方法是:

func AccountRegularExpression() -> NSRegularExpression {
    struct Singleton {
        static let sharedInstance = NSRegularExpression(pattern: self.AccountRegular, options: NSRegularExpressionOptions.CaseInsensitive, error: nil)
    }
    return Singleton.sharedInstance
}

或者只是删除该函数并使其成为计算属性:

var accountRegularExpression : NSRegularExpression {
    struct Singleton {
        static let sharedInstance = NSRegularExpression(pattern: self.AccountRegular, options: NSRegularExpressionOptions.CaseInsensitive, error: nil)
    }
    return Singleton.sharedInstance
}

或者,如果这在某个类中有意义,那么只需将其直接作为类的静态属性:

// inside some class
static let accountRegularExpression = NSRegularExpression(pattern: self.AccountRegular, options: NSRegularExpressionOptions.CaseInsensitive, error: nil)

答案 1 :(得分:0)

TL; DR:它看起来是正确的,它是一个函数的参数。

您对Objective-C中的块语法和Swift中的闭包(基本相同的)语法感到困惑。阅读swift语言文档中的函数/闭包部分,并参考以下页面:

答案 2 :(得分:0)

可能正确的翻译是 -

    class SomeClass
{
    static let regularPatternForRegularAccount = "Some Pattern";

    static let regularExpressionForRegularAccount = NSRegularExpression(pattern:SomeClass.regularPatternForRegularAccount,
                                options: NSRegularExpressionOptions.CaseInsensitive,
                                error: nil)

}

在这里,我们将正则表达式设为“静态释放”。并且它将被懒惰地评估,并且仅在第一次被访问时被评估。另请看:

singletons in swift