當我使用Swift進行核心數據提取請求時,我遇到了內存泄漏。但是,我在應用程序的不同部分中創建了幾乎相同的提取請求,但不會導致泄漏。在這兩種情況下,獲取請求都是在視圖控制器的viewDidLoad中進行的,並且獲取請求的結果被分配給視圖控制器的可選屬性。使用Swift核心數據提取請求中的內存泄漏
下面是不會引起任何泄漏的讀取請求的方法:
class LocationFilter {
//Lots of other code...
class func getAllPlacesOfRegionType<T: Region>(regionType: RegionType) -> [T] {
let fetchRequest = NSFetchRequest(entityName: regionType.rawValue)
var places: [T]
do {
places = try CoreDataStack.sharedInstance.context.executeFetchRequest(
fetchRequest) as! [T]
} catch let error as NSError {
NSLog("Fetch request failed: %@", error.localizedDescription)
places = [T]()
}
places.sortInPlace({ (firstPlace, nextPlace) -> Bool in
//Ingenious sorting code...
})
return places
}
}
這種方法被稱爲一個的viewController的viewDidLoad中,結果被分配給屬性var allRegions: [Region]?
沒有任何泄漏。下面的代碼:
class PlacesTableViewController: UITableViewController {
var allRegions: [Region]?
@IBOutlet weak var segmentedRegions: UISegmentedControl!
@IBAction func selectRegionSegment(sender: UISegmentedControl) {
// When the segmented control is tapped, the appropriate list will be loaded.
switch sender.selectedSegmentIndex {
case 0: //Country Segment
allRegions = LocationFilter.getAllPlacesOfRegionType(RegionType.Country)
case 1: //States segment
allRegions = LocationFilter.getAllPlacesOfRegionType(RegionType.Province)
case 2: //Cities segment
allRegions = LocationFilter.getAllPlacesOfRegionType(RegionType.City)
case 3: //Addresses segment
allRegions = LocationFilter.getAllPlacesOfRegionType(RegionType.Address)
default:
break
}
// Then reload the cells with animations.
let index = NSIndexSet(index: 0)
tableView.reloadSections(index, withRowAnimation: UITableViewRowAnimation.Automatic)
}
override func viewDidLoad() {
super.viewDidLoad()
selectRegionSegment(segmentedRegions)
}
}
下面的方法被調用viewDidLoad中不同的viewController的設置屬性var allDays: [Day]!
。
class DateFilter {
//Lots of other code in the class...
class func getAllDays() -> [Day] {
let fetchRequest = NSFetchRequest(entityName: "Day")
let days: [Day]
do {
days = try CoreDataStack.sharedInstance.context.executeFetchRequest(
fetchRequest) as! [Day]
} catch let error as NSError {
NSLog("Fetch request failed: %@", error.localizedDescription)
days = [Day]()
}
return days
}
}
在這裏它被稱爲:
class SearchViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var allDays: [Day]!
override func viewDidLoad() {
super.viewDidLoad()
allDays = DateFilter.getAllDays()
let backgroundView = UIView(frame: CGRectZero)
tableView.tableFooterView = backgroundView
tableView.backgroundColor = UIColor.groupTableViewBackgroundColor()
}
}
Xcode的儀器檢測內存泄漏時,這是調用。據推測負責的圖書館是libswiftFoundation.dylib
,負責的圖書館是static Array<A>._forceBridgeFromObjectiveC<A>(NSArray, result:inout [A]?) ->()
。當我查看Cycles & Root時,它在根處顯示NSArray
,+16 list: (null)
和+24 [no ivar]: (null)
分叉。
我做錯了我如何存儲我的提取請求的結果?或者這是Swift如何與Core Data交互的一個錯誤?
編輯:按照Mundi的建議整理代碼。 編輯2:添加了調用提取請求函數的代碼。
謝謝,我有完全相同的問題。你有沒有找出確切的原因? (泄漏對我來說只發生在iPhone 5s設備上,iPhone 6s和模擬iPhone 5s沒有泄漏。) – dvlpr
不客氣!不幸的是,我仍然不知道確切的原因。正如Mac Bellingrath所建議的那樣,我不能排除名稱空間衝突,但更改屬性的名稱並沒有爲我解決它。我開始認爲這是Apple框架中的一些東西;我懷疑這是由CoreData將返回的'NSArray'轉換爲Swift數組的方式引起的。 – ConfusedByCode
@dvlpr與iPhone 5s(9.3.1)設備上的OP具有相同的泄漏,我在iPhone 4(9.2.1)上沒有任何泄漏。順便說一下,我的實體與ConfusedByCode沒有任何關係。 –