2015-09-10 2 views
0

Я пытаюсь получить/хранить [String:Int] информацию в NSUserDefaults. Прекрасно работает , если Я построю с выпуском. Затем я получаю сбой на isEqual:. Код довольно ваниль здесь:Быстрая сбой при выпуске сборки при доступе к NSUserDefaults

private func storeVersion(storeName: String) -> UInt64 { 
    let settings = NSUserDefaults.standardUserDefaults() 
    let versions: [String:Int] 
    if let dict = settings.dictionaryForKey(storeVersionKey) as? [String:Int] { 
    versions = dict 
    } else { 
    versions = [ storeName : 0 ] 
    settings.setObject(versions, forKey: storeVersionKey) 
    settings.synchronize() 
    } 

    if let version = versions[storeName] { 
    return UInt64(version) 
    } 

    return 0 
} 

private func setStoreVerion(storeName: String, version: UInt64) { 
    let settings = NSUserDefaults.standardUserDefaults() 
    var versions: [String:Int] 
    if let dict = settings.dictionaryForKey(storeVersionKey) as? [String:Int] { 
    versions = dict 
    } else { 
    versions = [:] 
    } 
    versions[storeName] = Int(version) 
    settings.setObject(versions, forKey: storeVersionKey) 
    settings.synchronize() 
} 

Все, что я прочитал, говорит, что это должно работать нормально. Тем не менее, я получаю следующее сообщение аварии только в версиях выпуска:

0 
Crashed: com.apple.main-thread 
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x0000000027f5beb8 
raw 
0 
libobjc.A.dylib 
objc_msgSend + 16 
isEqual: 
1 
CoreFoundation 
CFEqual + 452 
2 
CoreFoundation 
-[CFPrefsPlistSource alreadylocked_setValue:forKey:] + 192 
3 
CoreFoundation 
-[CFPrefsSource setValue:forKey:] + 76 
4 
CoreFoundation 
+[CFPrefsSource withSourceForIdentifier:user:byHost:container:perform:] + 860 
5 
CoreFoundation 
_CFPreferencesSetValueWithContainer + 248 
6 
Foundation 
-[NSUserDefaults(NSUserDefaults) setObject:forKey:] + 56 
7 
PersistenceLayer  
_TF16PersistenceLayer11UpdateStoreFTSS9toVersionVSs6UInt64_T_ + 2264 

Line 7 имеет в виду этот код:

public func UpdateStore(storeName: String, toVersion version: UInt64) { 
    if storeVersion(storeName) >= version { 
    return 
    } 
    DeleteStoreNamed(storeName) 
    setStoreVerion(storeName, version) 
} 

Мало что отметить:

  • Я только скопировал часть остальной трассировки стека (остальные - процедуры запуска)
  • Строка 7 вызывает как storeVersion (первая проверка версии), а затем condi обновляя эту версию. Авария происходит при обновлении.
  • DeleteStoreNamed(_) просто удаляет два файла db с помощью NSFileManager. Больше ничего.
  • Это основная статья
  • Этот код содержится во встроенной структуре (модуле).
  • Это в настоящее время Swift 1.2 (не мигрировали до 2,0 еще)

ответ

0

Видимо, вопрос был мой использование [String:Int]. Это работало нормально, пока я не попытался использовать конфигурацию сборки Release. Что-то в процессе оптимизации не превратило тип во что-то, что может использовать объектно-с. Явным образом изменив тип на NSDictionary, прежде чем я отправил объект в NSUserDefaults, авария исчезла. Угадайте, что компилятор должен быть явно сказано, что делать.

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