2016-03-28 4 views
1

Я пишу расширение для NSDate, которое предоставляет некоторые отказоустойчивые инициализаторы. Конечной целью здесь является получение строки времени даты из API и ее анализ в NSDate, например.EXC_BAD_ACCESS в расширении форматирования NSDate

Строка времени
let createdAt = NSDate(apiDateTimeString: "2016-03-29T18:33:49+06:00") 
let createdAt = NSDate(apiDateTimeString: "2016-03-29T18:33:49.730+06:00") 

Дата может принять один из 2-х форматах:

  • yyyy-MM-dd'T'HH:mm:ssZZZZZ
  • yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ

Вот что расширение выглядит следующим образом:

import Foundation 

public extension NSDate { 

    // MARK: Custom Initializers 

    public convenience init(date: NSDate) { 
     self.init(timeInterval: 0.0, sinceDate: date) 
    } 

    public convenience init?(dateString: String, formatString: String) { 
     let formatter = NSDateFormatter() 
     formatter.dateFormat = formatString 
     formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") 
     if let date = formatter.dateFromString(dateString) { 
      self.init(date: date) 
     } else { 
      return nil 
     } 
    } 

    public convenience init?(apiDateTimeString: String?) { 
     guard let dateString = apiDateTimeString else { 
      return nil 
     } 
     if NSDate(dateString: dateString, formatString: "yyyy-MM-dd'T'HH:mm:ssZZZZZ") != nil { 
      self.init(dateString: dateString, formatString: "yyyy-MM-dd'T'HH:mm:ssZZZZZ") 
     } else { 
      self.init(dateString: dateString, formatString: "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ") 
     } 
    } 
} 

Когда я пытаюсь это использовать, он получает EXC_BAD_ACCESS по адресу if NSDate(dateString: dateString, formatString: "yyyy-MM-dd'T'HH:mm:ssZZZZZ") != nil

Любая помощь в выяснении причин, почему это не работает.

EDIT: Я забыл добавить: это работало с Swift 2.1, и перестал работать с Swift 2.2

ответ

5

Это вопрос в Swift 2.2. Для получения дополнительной информации см. SR-704: EXC_BAD_ACCESS on returning nil from a failable initializer of NSObject subclass. Похоже, он был исправлен в основной ветке, но не попал в финальную версию Swift 2.2. Ожидайте, что он будет исправлен в следующем обновлении точки.

Как временное обходное решение, обязательно всегда инициализируйте объект, прежде чем возвращать nil из отказавшего инициализатора (или выброса из инициализатора метания). То есть вставьте self.init() перед каждым заявлением return nil.

Редактировать: Эта проблема исправлена ​​в Swift 2.2.1/Xcode 7.3.1. Перед инициализацией экземпляра больше не нужно будет возвращать nil.

+0

Это было. Большое спасибо :) – Jonathan