2016-10-27 7 views
0

私はswift 3.0で書かれたプロジェクトに取り組んでいます。私の要件は、いくつかのテキストフィールドに入力し、それらの属性の1つをテーブルビューに入力してデータを保存し、行を選択するとそのレコードを更新する(テキストフィールドの値を再割り当てする)ことです。'NSTaggedPointerString'型の値を配列にキャストできません

私がcore dataに保存したデータをフェッチして配列に割り当てると、私のコードに問題があります。基本的に私は "タスク"という名前のエンティティを持っており、3つの属性を持っているので、コアデータに保存したこれらの属性(「名前」と呼ばれる)の1つをテーブルに表示したいので、以下の通りです。しかし、私のコードで次の行に "Could not cast value of type NSTaggedPointerString (0x10d8f7b90) to NSArray (0x10d8f7c58)"という例外があります。

エラーラインとコードは次のとおりです。ここで

tasks += expName as! [Task] 

私の完全なコードです:

import UIKit 
import CoreData 

class TableViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { 

@IBOutlet weak var tableView: UITableView! 

let appDelegate : AppDelegate = UIApplication.shared.delegate as! AppDelegate 
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 

var tasks = [Task]() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Do any additional setup after loading the view. 
} 

override func viewDidAppear(_ animated: Bool) { 

    //var error : NSError? 
    let request = NSFetchRequest <NSFetchRequestResult> (entityName: "Task") 
    request.returnsObjectsAsFaults = false 
    do { 

     let results = try context.fetch(request) 
     // check data existance 
     if results.count>0 { 
      print(results.count) 

      for resultGot in results as! [NSManagedObject]{ 

       if let expName = resultGot.value(forKey:"name"){ 
        print("expence name is :", expName) 
        tasks += expName as! [Task]  
        print("my array is : \(tasks)") 
       } 
      }  
     }  
    }catch{ 
     print("No Data to load") 
    } 
    self.tableView.reloadData() 
} 
override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 
    cell.textLabel?.text = tasks [indexPath.row] as? String 
    return cell 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return tasks.count 
} 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if segue.identifier == "ShowEditTask"{ 
    let v = segue.destination as! ViewController 
     let indexPath = self.tableView.indexPathForSelectedRow 
     let row = indexPath?.row 


    } 
} 
+0

問題に関連するコードのみを送信する必要があります。それ以外の場合は、読者が問題を見つけ出すまでに時間がかかります。たとえば、 'didReceiveMemoryWarning'や' viewDidLoad'は問題にはなりません。可能であれば、例外をスローするコード行を指定します。あなたは助けを受ける機会が増えます! –

+1

私は私の記述の下で問題があることを明確に示しています。 – danutha

+0

'results'はタスクの配列、' resultGot'はその配列のタスク、 'expName'はキー' name'の値です。コアデータモデルのタイプは何ですか?ストリング私は思いますか?なぜそれをタスクの配列にキャストしようとしていますか? – alexburtnik

答えて

0

エラーメッセージがNSTaggedPointerStringexpName)はNSArrayにキャストすることができないと言う([Task]

は、あなたの目標はありますnameプロパティがでない場合は、すべてTaskをタスク配列に追加します。という名前を付けてエラーを発生させようとしています。

ヒント:常にNSManagedObjectサブクラスの配列がそうすぐにそれをキャスト

fetch(context:戻ります。

NSManagedObjectサブクラスを使用しているので、valueForKeyではなくnameプロパティを直接取得します。

配列が空の場合にループがスキップされるため、> 0のチェックは不要です。

let results = try context.fetch(request) as! [Task] 
    // check data existance 
    print(results.count) 

    for task in results { 
    if let expName = task.name { 
     print("expence name is :", expName) 
     tasks += task  
     print("my array is : \(tasks)") 
    } 
    }  

または短い

let results = try context.fetch(request) as! [Task] 
tasks.filter{ $0.name != nil } 

最も効率的な方法は、適切な述語を経由してフェッチ前にタスクをフィルタリングすることです。

+0

に割り当てられるようにします。コードはラインタスク+ =タスクでエラーを起こしています – danutha

+0

'タスク' NSManagedObject'サブクラスですか? – vadian

関連する問題