問題は、この行にある:var templates: Dictionary<String, [String]> = [:]
:
templates[templateItem.templateType!]?.append(templateItem.templateText!)
templates
は、この行で初期化されました。この時点で、templates
は空の辞書です。
は年代順に、ダウンが起こるのステップにそのラインを破るのをしてみましょう:
templateItem.templateType
にアクセスして、開封さを強制されます。 nil
の場合、クラッシュが発生します。
templateItem.templateType!
は、templates
辞書のキーとして使用されます。これは常にnil
を返します。ディクショナリは空であるため、これを含むキーの値はありません。
?.append()
は、nil
で呼び出されていないという条件で呼び出されます。 nil
で呼び出された場合、何も起こりません。
3が原因です。あなたは1つが、まだキーのために存在していない場合は、新しい配列を初期化する必要があります。
func fetchTemplates() -> Dictionary<String, [String]> {
var templates: Dictionary<String, [String]> = [:]
let fetchRequest: NSFetchRequest<Template> = Template.fetchRequest()
fetchRequest.sortDescriptors = [SortDescriptor.init(key: "templateType", ascending: true)]
let fetchedData = try! context.fetch(fetchRequest)
if (!fetchedData.isEmpty) { //see note 2
for templateItem in fetchedData {
let type = templateItem.templateType!
var array = templates[type] ?? [] //see note 1
array!.append(templateItem.templateText!)
templates[type] = array
}
return templates
}
else {
return templates
}
}
この機能を簡素化することができる。
func fetchTemplates() -> [String : [String]] {
let fetchRequest = Template.fetchRequest()
fetchRequest.sortDescriptors = [SortDescriptor(key: "templateType", ascending: true)]
let fetchedData = try! context.fetch(fetchRequest)
var templates = [String, [String]]()
for templateItem in fetchedData {
let type = templateItem.templateType!
templates[type] = (templates[text] ?? []) + [templateItem.templateText!]
}
return templates
}
と削減を代わりに使用することができます。
func fetchTemplates() -> [String : [String]] { //see note 3
let fetchRequest = Template.fetchRequest() //see note 4
fetchRequest.sortDescriptors = [SortDescriptor(key: "templateType", ascending: true)] //see note 5
let fetchedData = try! context.fetch(fetchRequest)
return fetchedData.reduce([String, [String]]()){templates, templateItem in
(templates[templateItem.tempalteText!] ?? []) + [templateItem.templateText!]
} //see note 6
}
ノート
場合
- 0は
nil
ではなく、array
に割り当てられています。それ以外の場合は、新しい配列([]
)が `array 'に割り当てられます。
- このチェックは、明示的な型signiture
X.init()
のためだけ[String : [String]]
- 必要はちょうど
X()
- 空虚チェックは不要であると書かれていない、と全体
for
ことができるよう
Dictionary<String, [String]>
を書き込むことができ、不要ですループをreduce
コールに変更することができます。
サイドノート: '!fetchedData.isEmpty'のチェックは不要です。空の場合、forループは0回繰り返され、スキップされます。 – Alexander