私の以前のバージョンのアプリケーションでは、すべてのユーザーデータを(NSKeyedArchiverを使って).datファイルに保存しましたが、新しいバージョンでは、 。大量のデータをマイグレーションする際のメモリの問題を解決する
私はこのデータをすべてレルムにインポートしようとしています(それはたくさんあります)。しかし、それはあまりにも多くのメモリを取っているので、移行が完了する前にデバッガが最終的に私のアプリを殺すことになります。 「奇妙なこと」は、ハードディスクのデータがわずか1.5MBだが、1GB以上のメモリを使用しているため、何か間違っている。
私も複数のスレッドで作業しようとしましたが、それは役に立ちませんでした。さて、マイグレーションプロセスを高速化しました(これは良いですが)、同じ量のメモリが必要でした。
誰が私を助けることができますか? autoreleasepoolはトリックをした、
FYI非同期は私の質問のコメントのようにhttps://github.com/duemunk/Async
import Async
let startDate = NSDate(timeIntervalSince1970: 1388534400).startOfDay // Start from 2014 jan 1st
let endDate = NSDate().dateByAddingTimeInterval(172800).startOfDay // 2 days = 3600 * 24 * 2 = 172.800
var pathDate = startDate
let calendar = NSCalendar.currentCalendar()
let group = AsyncGroup()
var allPaths = [(Int, Int)]()
while calendar.compareDate(pathDate, toDate: endDate, toUnitGranularity: .Month) != .OrderedDescending {
// Components
let currentMonth = calendar.component(.Month, fromDate: pathDate)
let currentYear = calendar.component(.Year, fromDate: pathDate)
allPaths.append((currentYear, currentMonth))
// Advance by one month
pathDate = calendar.dateByAddingUnit(.Month, value: 1, toDate: pathDate, options: [])!
}
for path in allPaths {
group.background {
// Prepare path
let currentYear = path.0
let currentMonth = path.1
let path = (Path.Documents as NSString).stringByAppendingPathComponent("Stats_\(currentMonth)_\(currentYear).dat")
print(path)
if NSFileManager.defaultManager().fileExistsAtPath(path) {
NSKeyedUnarchiver.setClass(_OldStatisticsDataModel.self, forClassName: "StatisticsDataModel")
if let statistics = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? [_OldStatisticsDataModel] {
// Loop through days
for i in 1...31 {
let dateComponents = NSDateComponents()
dateComponents.year = currentYear
dateComponents.month = currentMonth
dateComponents.day = i
dateComponents.hour = 0
dateComponents.minute = 0
// Create date from components
let userCalendar = NSCalendar.currentCalendar() // user calendar
guard let date = userCalendar.dateFromComponents(dateComponents) else {
continue
}
// Search for order items
let filtered = statistics.filter {
if let date = $0.date {
let dateSince1970 = date.timeIntervalSince1970
return date.startOfDay.timeIntervalSince1970 <= dateSince1970 && date.endOfDay.timeIntervalSince1970 >= dateSince1970
}
return false
}
if filtered.isEmpty == false {
// Create order
let transaction = Transaction()
transaction.employee = Account.API().administratorEmployee()
let order = Order()
order.status = PayableStatus.Paid
order.createdDate = date.timeIntervalSince1970
order.paidDate = date.timeIntervalSince1970
// Loop through all found items
for item in filtered {
// Values
let price = (item.price?.doubleValue ?? 0.0) * 100.0
let tax = (item.tax?.doubleValue ?? 0.0) * 100.0
// Update transaction
transaction.amount += Int(price)
// Prepare order item
let orderItem = OrderItemm()
orderItem.amount = item.amount
orderItem.price = Int(price)
orderItem.taxPercentage = Int(tax)
orderItem.name = item.name ?? ""
orderItem.product = Product.API().productForName(orderItem.name, price: orderItem.price, tax: orderItem.taxPercentage)
// Add order item to order
order.orderItems.append(orderItem)
}
if order.orderItems.isEmpty == false {
print("\(date): \(order.orderItems.count) order items")
// Set transaction for order
order.transactions.append(transaction)
// Save the order
Order.API().saveOrders([order])
}
}
}
}
}
}
}
group.wait()
ループ内に多数のオブジェクトを割り当てています。ループ内で割り当てているオブジェクトの存続期間を制限するために、内部ループの本体を[autorelease pool](http://en.swifter.tips/autoreleasepool/)でラップすることをお勧めします。私はそれがあなたの問題に完全に対処するかどうかは分かりませんが、助けてください! – bdash
ここには、レルム固有のコードはありません。 Realmインスタンスはどこで開かれていますか、どこで 'autoreleasepool {}'にラップされていますか? – EpicPandaForce
@bdashありがとう、私はそれを見てみましょう。 autoreleasepoolについてはまだ経験がありません。 – NielsKoole