2017-02-17 8 views
0

私は、オーバーライドされたinit関数を持つオブジェクトを扱う関数を作成したいと考えています。これまでのところ、私はオーバーライドされたinit関数を使って作業していましたが、いくつかのロジックパーツで余分なコードを書く必要があるたびに、これらのオブジェクトを使って他のものを実行したいのですが。これを避け、コードをきれいにするためには、汎用関数witchを引数として持つようにしなければなりません。T.Type便利なコンストラクタをコアデータベースに追加するための汎用関数

これは作業部分を示し、私のサンプルコードです:

import Foundation 
import CoreData 


extension Sample { 

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Sample> { 
     return NSFetchRequest<Sample>(entityName: "Sample"); 
    } 

    @NSManaged public var smth: String 
    @NSManaged public var smth1: Double 

    convenience init(smth: String, smth1: Double, insertIntoManagedObjectContext _context: NSManagedObjectContext!) { 
     let _enitity = NSEntityDescription.entity(forEntityName: "Sample", in: _context) 
     self.init(entity: _entity, insertInto: _context) 
     self.smth = smth 
     self.smth1 = smth1 
    } 

} 

そして、私はこのようなオブジェクトを初期化:ここからexapmleに従うことで

let _context = DataBaseController.getContext() 

let _sample: Sample = Sample(smth: smth, smth1: smth1 insertIntoManagedObjectContext: _context) 
    DataBaseController.saveContext() 

を:Example

私は」これらの機能を実装しました:

func addRecord<T: NSManagedObject>(_ type : T.Type) -> T { 
     let _entityName = T.description() 
     let _context = DataBaseController.persistentContainer.viewContext 
     let _entity = NSEntityDescription.entity(forEntityName: _entityName, in: _context) 
     let _record = T(entity: _entity!, insertInto: _context) 
     return _record 
    } 

    func recordsInDataBase<T: NSManagedObject>(_ type : T.Type) -> Int { 
     let _records = allRecords(T.self) 
     return _records.count 
    } 

    func allRecords<T: NSManagedObject>(_ type : T.Type, sort: NSSortDescriptor? = nil) -> [T] { 
     let _context = DataBaseController.persistentContainer.viewContext 
     let _request = T.fetchRequest() 
     do { 
      let _results = try _context.fetch(_request) 
      return _results as! [T] 
     } catch { 
      print("Error : \(error)") 
      return [] 
     } 
    } 

私の質問は:とsmth1の2つの余分な引数を渡して、クラスからオーバーライドされたinit関数を呼び出すにはどうすればよいですか?

let _sample = DataBaseController.Instance.addRecord(...) 

ありがとうございます!

編集:

このようになりますか? :

let _sample = DataBaseController.Instance.addRecord(Sample.self.init(smth: smth, smth1: smth1, insertIntoManagedObjectContext: _context)) 
+0

'addRecord'のポイントは何ですか? 'let _sample:Sample = Sample(smth:smth、smth1:smth1 insertIntoManagedObjectContext:_context)'は既に新しいオブジェクトをデータベースに追加します。 – Sweeper

+0

このようにして試してみる必要はありませんか?それから私が引数として必要とする他のメソッドを呼び出すときは、 'Sample.self'を送り、' Sample'のインスタンスを指していることを知っていますか? – yerpy

+0

私はあなたがそれを意味するものを実際に得ていません。あなたの究極の目標は何ですか? – Sweeper

答えて

1

これはできません。

リンクした例では、きれいな小さな機能を使用してデータベースを保存してクエリする方法を示しています。関数に余分なパラメータを魔法のように渡すことはできませんし、それらを受け入れて新しい "レコード"を作成するために使うことを期待しています。あなたがaddRecordを使用する方法である

let name = "John Appleseed" 

let newContact = addRecord(Contact.self) 
newContact.contactNo = 1 
newContact.contactName = name 

回答は、実際にどのようにビットをスクロールダウンした場合の機能を使用する方法を示しました。 addRecordと呼び出し、WhateverType.selfを渡し、戻り値を変数に代入します。その後、初期化子を使用して、変数のプロパティをに直接設定しません。

私はこの(非常にエレガントではない)解決策が出ている:今、すべてのNSManagedObjectこのinitialize(with:)メソッドを持ってい

extension NSManagedObject { 
    func initialize(with properties: [String: Any]) { 

    } 
} 

class Sample : NSManagedObject { 
    override func initialize(with properties: [String : Any]) { 
     self.smth = properties["smth"] as! String 
     self.smth1 = properties["smth1"] as! Double 
    } 

    @NSManaged var smth: String 
    @NSManaged var smth1: Double 

    convenience init(properties: [String: Any], insertIntoManagedObjectContext _context: NSManagedObjectContext!) { 
     let _enitity = NSEntityDescription.entity(forEntityName: "Sample", in: _context) 
     self.init(entity: _enitity!, insertInto: _context) 
    } 
} 

。だから、addRecord方法では、あなたは、所望の特性を持つ新しい管理対象オブジェクトを初期化することを呼び出すことができます。

func addRecord<T: NSManagedObject>(_ type : T.Type, properties: [String: Any]) -> T { 
    let _entityName = T.description() 
    let _context = DataBaseController.persistentContainer.viewContext 
    let _entity = NSEntityDescription.entity(forEntityName: _entityName, in: _context) 
    let _record = T(entity: _entity!, insertInto: _context) 
    _record.initialize(with: properties) 
    return _record 
} 

使用例:

addRecord(Sample.self, properties: ["smth": "Hello", "smth1": 1]) 

をこの程度の悪い事は何のタイプが存在しないことはもちろんです安全性。 addRecordに渡すすべての物件はAnyです。

+0

ええ、私はこれについて考えるつもりです。ご回答有難うございます !私はあなたのポイントを持っています! – yerpy

関連する問題