2015-01-04 3 views
0
var defaults = NSUserDefaults.standardUserDefaults(); 
    var titlesForTip : [NSString]? = defaults.objectForKey("titleForTipSegment") as? [NSString] 
    if titlesForTip == nil  //Check for first run of app 
    { 
     titlesForTip = ["18%", "20%", "22%"]; //Default value 
    } 
    // it is ok to get first and last elements 
    println(titlesForTip?.first) 

    for item in titlesForTip {//**error [NSString]? does not have a member named Generator** 
     println(item) 
    } 
    //**error type [NSString]? does not conform to protocol sequence type** 
    for (var index, var value) in enumerate(titlesForTip) { 
     println("Item \(index + 1): \(value)") 
    } 

    titlesForTip[1];//**error [NSString]? does not have a member named subscript** 

В окне отладки отображаются заголовкиForTip, включающие в себя 3 элемента и отображаемые в названияхForTip [0] ... titlesForTip [2], но я не могу посетить его с помощью [].Как перезапустить NSString в Swift?

он работает в Xcode 6.1.1, я не знаю, как итерации с ним.

Ошибка в моем коде: var titlesForTip: [NSString]? = defaults.objectForKey ("titleForTipSegment") как? [NSString] if (titlesForTip? == nil || titlesForTip! == []) // Проверка первого запуска приложения { titlesForTip = ["18%", "20%", "22%"]// Значение по умолчанию } objectForKey вернет нулевой массив, когда ничего не будет, поэтому titlesForTip == nil никогда не произойдет.

+1

titlesForTip является необязательным. Вам нужно развернуть его. –

ответ

1

Вы создали titlesForTip как необязательный, который может содержать массив NSStrings. Поэтому вам нужно проверить, содержит ли он что-либо, распакуя его, прежде чем вы сможете получить доступ к его элементам или выполнить итерацию на нем.

Используйте код похож на этот:

var defaults = NSUserDefaults.standardUserDefaults() 
var titlesForTip : [NSString]? = defaults.objectForKey("titleForTipSegment") as? [NSString] 
if titlesForTip == nil  //Check for first run of app 
{ 
    titlesForTip = ["18%", "20%", "22%"] //Default value 
} 

if let unwrappedTitlesForTip = titlesForTip { 
    // it is ok to get first and last elements 
    println(unwrappedTitlesForTip.first) 

    for item in unwrappedTitlesForTip { 
     println(item) 
    } 

    for (var index, var value) in enumerate(unwrappedTitlesForTip) { 
     println("Item \(index + 1): \(value)") 
    } 

    unwrappedTitlesForTip[1] // need to do something with this, won't work just on a line on its own 
} 

В качестве альтернативы, вы можете установить его, чтобы вы не использовать опциональный, установив значение по умолчанию первый, и опрокинув его, если вы получаете что-то от NSDefaults, как это:

var defaults = NSUserDefaults.standardUserDefaults() 
var titlesForTip : [NSString] = ["18%", "20%", "22%"] 
if let storedValue = defaults.objectForKey("titleForTipSegment") as? [NSString] { 
    titlesForTip = storedValue 
} 

// it is ok to get first and last elements 
println(titlesForTip.first) 

for item in titlesForTip { 
    println(item) 
} 

for (var index, var value) in enumerate(titlesForTip) { 
    println("Item \(index + 1): \(value)") 
} 

titlesForTip[1] // need to do something with this, won't work just on a line on its own 
+0

Спасибо, что отлично. В мире C/C++, если (a = b) всегда производит true, я не знаю, почему быстрая работа таким образом, хотя она добавила let перед a = b. –

+0

Swift 'if let a = b' pattern - это способ объединения теста необязательного значения для nil и разворачивания значения внутри этого необязательного (если он есть) в одно и то же время. –

0

Как вы сказали, это только потому, что ваш массив заворачивают в Опционно - потому что вы завернул его в необязательном с помощью оператора as?. Это нормально, и это мудрая идея, потому что это безопасно. Но тогда вы должны разворачивать его:

var titlesForTip : [NSString]? // "wrap me in an Optional" 
titlesForTip = ["18%", "20%", "22%"] 
for item in titlesForTip! { // "unwrap me" 
    println(item) 
} 

В реальном коде, что я хотел бы сделать, это использовать условное связывание разворачивать:

var titlesForTip : [NSString]? = 
    defaults.objectForKey("titleForTipSegment") as? [NSString] 
if let titlesForTip = titlesForTip { "unwrap me safely" 
    // ...here, titlesForTip is unwrapped and safe to use... 
} 

Однако, на самом деле нет необходимости в какой-либо из этот код, потому что нет необходимости проверять значение nil и предоставлять значение по умолчанию. Вместо этого позвоните по телефону registerDefaults: - вот для чего это. Таким образом, objectForKey("titleForTipSegment") будет всегда имеют значение [NSString], и вы можете просто бросить безоговорочно.

+0

Спасибо, я закончил это таким образом, будет ли это безопасно? titlesForTip = defaults.objectForKey ("titleForTipSegment") как? NSMutableArray if (titlesForTip? == nil || titlesForTip! == []) // Проверка первого запуска приложения { titlesForTip = [0.18, 0.20, 0.22]; } –

+0

Я так полагаю, но это не идеальный способ подачи по умолчанию для первого запуска. Вызов 'registerDefaults:'; для чего это нужно. Таким образом, _always_ будет объектом для этого ключа, и вам не придется проверять нуль вообще. См. Мой ответ здесь: http://stackoverflow.com/a/15991061/341994 – matt

+0

Добавлен упоминание 'registerDefaults:' к моему ответу. – matt

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