2016-10-05 25 views
1

私は200,000行のcsvファイルを持っています。文字数が1874を超える文字列プロパティを持つオブジェクトを追加するSwiftがクラッシュする

各行には9個の値が含まれ、すべての行文字列の文字数は2048未満ですが、3行の文字数は4420になります。これらの行のインデックスはそれぞれ134481,13482,134483です。行の最後の文字列値の9個の値のうち大きい値です。以下

行134481がレルムに追加またはレルムで作成される場合、それはBpTreeでクラッシュし得る:: EXC_BAD_ACCESSとcreate_root_from_mem(コード= 2、アドレス= XXXXX)

はSWIFTコード[SWIFTバージョン2.2、Xcodeのあります:7.3、realmSwift:1.1.0] ... csvオブジェクトをrealmデータベースに追加するためのものです。

このコードはバックグラウンドキューで実行されています。最初の130k行をスキップしてみましたが、それでも行134481で正確にクラッシュしました。文字列の文字カウントを減らした後でも、オブジェクトはクラッシュせずに追加されます。

class PackageObject:Object { 
    dynamic var id = "" 
    dynamic var packageBatch = "" 
    dynamic var packageCode = "" 
    dynamic var packageDescription = "" 
    dynamic var packageName = "" 
    dynamic var packagelocalName = "" 
    dynamic var packageNumber = "" 
    dynamic var packageBuild = "" 
    dynamic var packageSummary = "" 
} 

let filename = NSBundle.mainBundle().pathForResource("codes", ofType: "tsv") 
    if let realm = try? Realm(configuration: configuration), data = try? String.init(contentsOfFile: filename!) { 
     let block = 5000 
     var lineNumber = 0 
     print(realm.configuration.fileURL) 

     data.enumerateLines({ (line, stop) in 
      if lineNumber % block == 0 { 
       print("begin: ", lineNumber) 
       realm.beginWrite() 
      } 
      lineNumber += 1 
      var strings = line.componentsSeparatedByString("\t") 

      if lineNumber >= 134481 && lineNumber <= 134483 { 
       // strings[8] count is about 3805 
       // after reducing the count to 1874, the object 
       // is successfully added to the realm, else a crash is observed. 
       let count = strings[8].characters.count 
       print(count, line.characters.count) 
       let index = strings[8].endIndex.advancedBy(1931 - count) 
       strings[8].removeRange(index..<strings[8].endIndex) 
      } 

      let packageObj = PackageObject(value: strings) 
      realm.add(packageObj) 
      //realm.create(PackageObject.self, value:strings) 
      if lineNumber % block == 0 { 
       print("commit: ", lineNumber) 
       _ = try? realm.commitWrite() 
      } 
     }) 
    } 

    // The last commitWrite is not handled...inside the block. 
    // for the below condition... 
    if lineNumber % block != 0 { 
     _ = try? realm.commitWrite() 
    } 

realm docは、Stringプロパティが16MB未満である可能性がありますが、ここでは10KBも取らないことを示しています。

文字列に間違いはありません。それは単なる英語のテキストです。これはバグですか、別の方法でオブジェクトを追加する必要がありますか?

答えて

1

文字列プロパティがインデックスされている場合は、2.0にアップグレードするとこれが解決される可能性があります。

古いバージョンには、文字列が十分に長い共通接頭辞を持つときにスタックオーバーフローに繋がるインデックスの実装方法に欠陥があり、再帰を削除するためにインデックスが格納される方法が変更されました。

+0

正確に何が起こっているかは、私はそれにインデックスがあり、長い共通プレフィックスを持っているようです。 Swift 2.3でRealmSwift 2.0が利用可能です。 – RK1979

+0

スウィフト2.3、スウィフト2.2 – RK1979

関連する問題