2017-03-09 31 views
2

我有,我用它來更新行已經改變了境界封閉: 斯威夫特字典需要長時間來編譯

try realm.write { 

        realm.create(Product.self, value: ["itemgroup": item.itemgroup, 
                "itembrand": item.itembrand, 
                "itemtype": item.itemtype, 
                "itemsubtype": item.itemsubtype, 
                "basedescription": item.basedescription, 
                "info": item.info, 
                "upc": item.upc, 
                "upc2": item.upc2, 
                "upc3": item.upc3, 
                "upc4": item.upc4, 
                "upc5": item.upc5, 
                "baseprice": item.baseprice, 
                "proprice": item.proprice, 
                "retailprice": item.retailprice, 
                "stdprice": item.stdprice, 
                "caseqty": item.caseqty, 
                "spord": item.spord, 
                "category": item.category, 
                "categorycode": item.categorycode, 
                "allowinbc": item.allowinbc, 
                "allowinab": item.allowinab], update: true) 
       } 

然而,它採取了10分鐘編譯!

這裏是我的模型類:

class Product: Object { 

    dynamic var itemno: String = "" 
    dynamic var itemgroup: String = "" 
    dynamic var itembrand: String = "" 
    dynamic var itemtype: String = "" 
    dynamic var itemsubtype: String = "" 
    dynamic var basedescription: String = "" 
    dynamic var info: String = "" 
    dynamic var upc: String = "" 
    dynamic var upc2: String = "" 
    dynamic var upc3: String = "" 
    dynamic var upc4: String = "" 
    dynamic var upc5: String = "" 
    dynamic var baseprice: Double = 0.00 
    dynamic var proprice: Double = 0.00 
    dynamic var retailprice: Double = 0.00 
    dynamic var stdprice: Double = 0.00 
    dynamic var caseqty: Int = 0 
    dynamic var spord: String = "" 
    dynamic var category: String = "" 
    dynamic var categorycode: String = "" 
    dynamic var allowinbc: String = "" 
    dynamic var allowinab: String = "" 

    override class func primaryKey() -> String { 
     return "itemno" 
    } 

    convenience init(itemno: String, itemgroup: String, itembrand: String, itemtype: String, itemsubtype: String, basedescription: String, info: String, upc: String, upc2: String, upc3: String, upc4: String, upc5: String, baseprice: Double, proprice: Double, retailprice: Double, stdprice: Double, caseqty: Int, spord: String, category: String, categorycode: String, allowinbc: String, allowinab: String) { 

     self.init() 
     self.itemno = itemno 
     self.itemgroup = itemgroup 
     self.itembrand = itembrand 
     self.itemtype = itemtype 
     self.itemsubtype = itemsubtype 
     self.basedescription = basedescription 
     self.info = info 
     self.upc = upc 
     self.upc2 = upc2 
     self.upc3 = upc3 
     self.upc4 = upc4 
     self.upc5 = upc5 
     self.baseprice = baseprice 
     self.proprice = proprice 
     self.retailprice = retailprice 
     self.stdprice = stdprice 
     self.caseqty = caseqty 
     self.spord = spord 
     self.category = category 
     self.categorycode = categorycode 
     self.allowinbc = allowinbc 
     self.allowinab = allowinab 
    } 

} 

我可以做我的代碼,將加快編制是什麼?

謝謝。

+0

在您的示例代碼,什麼'item'的類型? – idz

+0

@idz''item''是類型'Product',我的模型類。這是一個常量,它包含一個用便利初始值設定項實例化的Product的實例。 – Sicypher

+1

幾乎完美通過https://spin.atomicobject.com/2016/04/26/swift-long-compile-time/ – BallpointBen

回答

2

因爲所有的答案都非常有幫助,所以在這裏並沒有真正的'最佳'答案。編譯大型Swift字典的最快方法是不要讓編譯器推斷任何東西的類型。這意味着您需要定義字典中每個項目的數據類型(包括字典本身)。

我的字典編制的最快方法是:

try realm.write { 

       let dict: [String: Any] = ["itemgroup": item.itemgroup as String, 
             "itembrand": item.itembrand as String, 
             "itemtype": item.itemtype as String, 
             "itemsubtype": item.itemsubtype as String, 
             "basedescription": item.basedescription as String, 
             "info": item.info as String, 
             "upc": item.upc as String, 
             "upc2": item.upc2 as String, 
             "upc3": item.upc3 as String, 
             "upc4": item.upc4 as String, 
             "upc5": item.upc5 as String, 
             "baseprice": item.baseprice as Double, 
             "proprice": item.proprice as Double, 
             "retailprice": item.retailprice as Double, 
             "stdprice": item.stdprice as Double, 
             "caseqty": item.caseqty as Int, 
             "spord": item.spord as String, 
             "category": item.category as String, 
             "categorycode": item.categorycode, 
             "allowinbc": item.allowinbc as String, 
             "allowinab": item.allowinab as String] 

       realm.create(Product.self, value: dict, update: true) 
      } 
+0

'as'語句是否顯着加快編譯速度? – BallpointBen

+0

是的,@BallpointBen。這樣做之後,字典的編譯時間就會低於10毫秒! – Sicypher

+0

我不懷疑你是對的。但是... geez。爲什麼編譯器甚至關心具有「任何」值的字典中的值的類型?我希望它不浪費時間檢查與「任何」的子類型關係的值... – BallpointBen

2

我遇到與創建大型辭書這個bug。一種選擇是創建多個步驟,然後改變字典:

var dict: [String: Any] = ["itemgroup": item.itemgroup] 
dict["itembrand"] = item.itembrand 
// Populate rest of dictionary as above 

try realm.write { 
    realm.create(Product.self, value: dict) 
} 
+0

這在這種情況下不起作用。如果'item.itemGroup'是一個'String',字典類型將被推斷爲'[String:String]'。然後將不可能添加「雙」值,例如'baseprice'。 – Sulthan

+0

好點。顯式聲明該類型是一個很簡單的修復。 – Connor

+0

您應該使用'Any'而不是'AnyObject',否則您將在每個值類型上發出警告,您必須將其轉換(例如'as NSString'或'as AnyObject')以使其靜音。 – Sulthan

0

這裏的問題與Realm不同;它是Swift編譯器。編寫大型字典很困難。由於item已經是Product類型,所以您可以直接將其添加到領域(但您說它是不變的,所以這可能會涉及到代碼的一些結構更改)。

另一種選擇是,以取代你寫塊體:與斯威夫特慢編譯問題

let p = Product(value: item) 
realm.add(p) 
+0

我在if語句中有''realm.add()''。我的問題中顯示的代碼位於else塊內。如果該項目不存在,則會添加''realm.add()'',否則,如果我的API中的項目信息與設備上存儲的信息不同,則該項目會更新爲''realm .create()'' – Sicypher

+1

如果它是一個更新使用'realm.add(p,update:true)',但要注意更新,你必須提供主鍵。 – idz

1

99%的輸入推斷相關。這在複雜表達式中(當編譯器必須搜索太多可能性時)或從不同類型創建大型字典時最爲明顯。

作爲一種變通方法,您可以隨時關閉類型推斷關閉通過指定期望的類型,例如:

let dictionary: [String: Any] = [ 
    "itemgroup": item.itemgroup, 
    ... 
] 
realm.create(Product.self, value: dictionary)