使用 Switch 语句将 Swift convenience init 转换为 Objective-C

Convert Swift convenience init with Switch statement to Objective-C

我正在尝试将此 swift 代码转换为 Objective-C

convenience init(fromString string: String, format:DateFormat)
    {
        if string.isEmpty {
            self.init()
            return
        }

        let string = string as NSString

        switch format {

        case .DotNet:

            let startIndex = string.rangeOfString("(").location + 1
            let endIndex = string.rangeOfString(")").location
            let range = NSRange(location: startIndex, length: endIndex-startIndex)
            let milliseconds = (string.substringWithRange(range) as NSString).longLongValue
            let interval = NSTimeInterval(milliseconds / 1000)
            self.init(timeIntervalSince1970: interval)

到目前为止,我正在这样做:

-(id) initFromString: (NSString *) string format: (DateFormat *) format{
    if (string == nil) {
        self = [self init];
        return self;
    }


    switch (format) {
        case .DotNet:
            NSRange *startIndex = [[string rangeOfString:@"("] location]+1;

    }
}

并且已经 运行 出现以下错误:

for the switch(format): statement requires expression of integer type (DateFormat * __strong' invalid)

以及以下 2 行:预期表达式

有什么想法吗?

在 Objective-C 中,字符串是隐式可选的。测试 nil 仅测试是否提供了字符串。它不检查是否提供了空字符串。您可能想切换到 string.length == 0,因为借助 nil-messaging 的魔力,它可以检查空字符串或根本没有字符串。

Objective-C 使用 C 的 switch 语句。所以你只能打开整数类型。如果这是最初的 Objective-C 代码,DateFormat 可能是 NS_ENUM — 整数类型而不是对象类型。看起来原来是你使用点语法的枚举?如果你可以使它成为一个 Objective-C 枚举然后这样做并简单地使用:

- (id)initFromString:(NSString *)string format:(DateFormat)format {
    ....
    switch(format)
    {
        case DateFormatDotNet: {
            ....
        } break;
    }

case 中的大括号是因为您想在其中声明变量)。

否则,如果它必须是对象格式,那么您正在寻找一个痛苦的结构,例如:

if([format isEqual:[DateFormat dotNetFormat]]) {
}
else if([format isEqual:[DateFormat otherFormat]]) {
}
... etc ...

此外 Objective-C 在 structs 之间有句法区别,这正是它们在 C 中的含义——命名字段但没有内置行为——和对象类型,这又是因为它是C 的严格超集。 NSRange 是一个结构。所以方括号消息传递语法不适用于它。而不是:

[[string rangeOfString:@"("] location]

使用:

[string rangeOfString:@"("].location

方括号围绕 rangeOfString 调用,因为它是对对象的消息分派,然后是位置的点,因为您返回一个 C 结构作为值,这就是访问 C 中的字段的方式结构。

(点语法也适用于 Objective-C 对象的属性,但明确地为 getter 和 setter 调用设置别名,并且仅适用于最近的 Objective-C的三个十年)

假设此代码与

相关

由于您的 DateFormat 变量是一个带有 dateFormatType 的对象,它是一个 NSString,因此您将不得不使用链式 if-else 构造来 select 来自各种可能性:

if([format.dateFormatType compare: DotNetDateFormatType] == NSOrderedSame) {
    [self handleDotNetDateFormat: format]
} else if ([format.dateFormatType compare: RSSDateFormatType] == NSOrderedSame) {
   [self handleRSSDateFormat: format]
...

Objective-C 没有枚举值的点值语法概念(因此“.DotNet”在 Objective-C 中不是有效术语)。这就是编译器抱怨这两行的原因。