2016-04-12 6 views
0

Я пытаюсь преобразовать этот быстрый код 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 switch(format): инструкция требует выражения целочисленного типа (DateFormat * __strong 'недействительна)

и для следующих двух строк: Ожидаемое выражение

Любые идеи?

+0

was DateFormat перечисление в быстром коде? вы изменили его на класс в коде objc, передав в формате 'format' как указатель на экземпляр DateFormat. Компилятор не хочет, чтобы вы включили такой указатель. –

+0

Немного не по теме, но в текущем мире ваш init должен возвращать «instancetype» вместо id. Просто подсказка для компилятора. –

ответ

2

В Objective-C строка подразумевается необязательно. Тестирование для nil просто проверяет, была ли поставлена ​​строка. Он не проверяет, была ли предоставлена ​​пустая строка. Вероятно, вы захотите переключиться на string.length == 0, так как магия nil-messaging будет работать для проверки пустой строки или вообще никакой строки.

Объектив-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 имеет синтаксическое различие между struct с, что именно то, что они находятся в C - названные поля, но не встроенное поведение - и типы объектов, что опять же потому, что это строгий суперсет C. NSRange - это структура. Поэтому синтаксис синтаксиса с квадратной скобкой не работает. Вместо того, чтобы:

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

Использование:

[string rangeOfString:@"("].location 

Квадратные скобки вокруг rangeOfString вызова, потому что это сообщение отправка к объекту, то точка на месте, потому что вы получите обратно C-структуру в качестве значения, и это то, как один доступ к полю в C-структуре.

(точечный синтаксис работает также для свойств на объекты Objective-C, но явно псевдоним для получения и установки вызовов, а только о самой последней из Objective-C три десятилетия в)

+0

Как насчет ошибки startIndex? говорит мне: плохой тип приемника «NSRange» (aka «struct_NSRange») –

+0

Еще один фрагмент остатка от Objective-C, оставляющий программиста для разбора разницы между 'struct' (которые являются C-типом, то есть хранилищем с именем-поля без логики, которые являются либо значениями, либо ссылочными типами, что сильно отличается от сортировки Swift) и объектов. Я обновлю ответ. – Tommy

+0

Последний вопрос: как вы его преобразуете в Objective-C? self.init (timeIntervalSince1970: interval) –

0

Предполагая, что этот код связана в How to convert a Swift enum: String into an Objective-C enum: NSString?

Поскольку переменная DateFormat является объектом с dateFormatType, который является NSString, вы будете иметь, чтобы использовать прикован если-нибудь конструкцию, чтобы выбрать из различных возможностей:

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

Objective-C не имеет понятия синтаксиса dot-value для значений enum (поэтому «.DotNet» не является допустимым термином в Objective-C). Вот почему компилятор жалуется на эти строки.

+0

Как насчет ошибки startIndex? говорит мне: плохой тип приемника «NSRange» (aka «struct_NSRange») –

+0

NSRange - это объект struct, а не объект объектива-C. Вы используете его в структуре передачи сообщений '[[string rangeOfString: @" ("] location]'. Просто используйте '[string rangeOfString: @" ("]. Location' –

+0

Благодарим за помощь! дайте +1, но моя репутация недостаточно высока:/EDIT: я действительно мог это сделать, но он появится только после того, как я доберусь до 15 человек. –

 Смежные вопросы

  • Нет связанных вопросов^_^