2014-11-24 1 views
0

내가 슈퍼 간단한 기본 응용 프로그램이하는 collectionView와이 이상하게 메모리 누수 신속 아이폰 OS

단지 하나 개의 ViewController는

그것은 내 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를 설정에서 지정하십시오.

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

누수가 없지만 해결책이 될 수 없습니까?

답변

2

이전에 NIB로드와 관련된 신속한 버그로 인해 속성을 두 번 초기화 할 수 있습니다. 정확하게 기억한다면 어떤 경우에는 동일한 객체 인스턴스에서 두 개의 다른 지정된 초기화 프로그램을 호출하여 객체의 인스턴스 속성을 두 번 초기화하고 아무것도 초기화하지 않은 채 누출 된 것을 초기화 할 수 있습니다. (그 코코아 응용 프로그램에서 NSWindowController 사용하여 일찍 스위프트 베타있었습니다. 현재 Swift 버전에서 버그가 여전히 있는지 여부를 알 수 없습니다.)

당신의 collectionViewLayout 속성을 볼 수 누수가 설명 할 것이다, setup()에 속성을 할당 할 때 누수가 발생하지 않는 이유는 무엇입니까?

당신은 UICollectionViewFlowLayout 인스턴스가 만들어 얼마나 많은보고 악기를 사용하거나, 당신은 당신의 ViewController 초기화하는 동안 두 번이라고하는지 -[UICollectionViewFlowLayout init]에 상징적 중단 점을 설정할 수 있습니다.

그렇지 않으면 누설 감지기에서 위양성 일 수 있습니다.

이 문제를 해결하려면 당신은 init(coder:) 최우선을 시도하고 그 방법에 collectionViewLayout 속성을 초기화 할 수 있습니다 :

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

그러나이 초기화가 두 번 호출되지 않는다는 것을 확인 할 수 있습니다.

+0

예 내 breakpoint가 init 메소드의 2 배에 해당하는 것으로 보입니다.이 문제를 해결하는 방법에 대한 제안은 무엇입니까? –

+1

그것 같이 보인다 : http://stackoverflow.com/a/26310782/62009 나를 도와 줘서 고마워. 이중 초기화의 방향으로. –

0

CollectionViewdelegatedatasource이므로 보유주기 (누수)가 발생하지 않도록 weak으로 지정해야합니다.