2014-11-24 49 views
0

我有一個超級簡單的基本應用,無法解釋的內存泄漏迅速的iOS

僅有1個視圖 - 控制用的CollectionView

它接縫泄漏我的collectionViewFlowLayout,我不知道爲什麼

Leaked Object # Address Size Responsible Library Responsible Frame 
__NSDictionaryM 1 0x7fcc4ca31340 48 Bytes UIKit UICollectionViewLayoutCommonInit 
__NSDictionaryM 1 0x7fcc4ca313a0 48 Bytes UIKit UICollectionViewLayoutCommonInit 
__NSDictionaryI 1 0x7fcc4ca31570 64 Bytes UIKit UICollectionViewFlowLayoutCommonInit 
__NSDictionaryM 1 0x7fcc4ca313d0 48 Bytes UIKit UICollectionViewLayoutCommonInit 
UICollectionViewFlowLayout 1 0x7fcc4ca310c0 512 Bytes leak-application ObjectiveC.UICollectionViewFlowLayout.__allocating_init (ObjectiveC.UICollectionViewFlowLayout.Type)() -> ObjectiveC.UICollectionViewFlowLayout 
__NSDictionaryM 1 0x7fcc4ca31370 48 Bytes UIKit UICollectionViewLayoutCommonInit 
__NSDictionaryM 1 0x7fcc4ca31400 48 Bytes UIKit UICollectionViewLayoutCommonInit 
NSMutableIndexSet 1 0x7fcc4ca314e0 48 Bytes UIKit UICollectionViewLayoutCommonInit 
NSMutableIndexSet 1 0x7fcc4ca31470 48 Bytes UIKit UICollectionViewLayoutCommonInit 
__NSDictionaryM 1 0x7fcc4ca2f290 48 Bytes UIKit UICollectionViewLayoutCommonInit 

這是我的代碼

class ParallaxCollectionViewCell: UICollectionViewCell { 

    let titleLabel = UILabel(frame: CGRectMake(0, 0, 100, 100)) 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     self.contentView.addSubview(titleLabel) 
    } 

    required init(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

} 

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { 

    var collectionView: UICollectionView? 
    let collectionViewLayout = UICollectionViewFlowLayout() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     setup() 
    } 

    func setup() { 

     self.collectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: self.collectionViewLayout) 
     self.view.addSubview(self.collectionView!) 

     self.collectionView?.delegate = self; 
     self.collectionView?.dataSource = self; 
     self.collectionView?.backgroundColor = UIColor.whiteColor() 
     self.collectionView?.registerClass(ParallaxCollectionViewCell.self, forCellWithReuseIdentifier: "identfifier") 

     self.collectionView?.reloadData() 
    } 

    override func viewDidLayoutSubviews() { 
     self.collectionView?.frame = self.view.bounds 
    } 

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { 
     return CGSizeMake(CGRectGetWidth(self.view.bounds), 100) 
    } 

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
     let parallaxCell = collectionView.dequeueReusableCellWithReuseIdentifier("identfifier", forIndexPath: indexPath) as ParallaxCollectionViewCell 
     parallaxCell.titleLabel.text = "test" 
     return parallaxCell 
    } 

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 10 
    } 
} 

如果我使collectionViewLayout屬性一個可選的變種,並在設置中指定它

var collectionViewLayout : UICollectionViewFlowLayout? 
func setup() { 
    self.collectionViewLayout = UICollectionViewFlowLayout() 
    self.collectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: self.collectionViewLayout!) 
    ... 

它不會泄漏..但那不可能是解決方案嗎?

回答

2

我以前遇到過與NIB加載相關的Swift錯誤,這可能會導致屬性被初始化兩次。如果我沒有記錯,在某些情況下,可能會在同一個對象實例上調用兩個不同的指定初始化器,從而導致對象的實例屬性被初始化兩次,並在第一次初始化期間泄漏了任何實例。 (這是在Cocoa應用程序中使用NSWindowController早期斯威夫特測試階段。我不知道如果bug在當前斯威夫特版本仍然存在。)

這可以解釋你與你的collectionViewLayout財產看到泄漏,以及爲什麼在您指定setup()中的屬性時它不會泄漏。

您可以使用儀器,看看有多少創建UICollectionViewFlowLayout情況下,也可以在-[UICollectionViewFlowLayout init]設置一個斷點標誌,看它是否是你的ViewController初始化過程中調用兩次。

否則,它可能只是泄漏檢測器的誤報。

要解決這個問題,你可以嘗試重寫init(coder:)並在該方法初始化collectionViewLayout屬性:

required init(coder aDecoder: NSCoder) { 
    self.collectionViewLayout = UICollectionViewFlowLayout() 
    super.init(coder:aDecoder) 
} 

但是,你要確認這個初始化中調用兩次。

+0

是的,似乎我的斷點碰到兩次init方法,有關如何解決此問題的任何建議? – 2014-11-24 14:25:46

+1

似乎是這樣的:http://stackoverflow.com/a/26310782/62009幫助我,謝謝指出我在雙重初始化的方向。 – 2014-11-24 14:38:35

0

由於CollectionViewdelegatedatasource你應該宣佈它作爲weak避免保留週期(泄漏)。