2017-02-16 49 views
0

Swift還很新,閱讀了解「最佳實踐」,我試圖重構一些簡單的代碼,但無法繞過選項並將簡單的UICollectionView放在一個簡單的代碼中UIViewControllerUIViewController中的集合視圖可選的展開崩潰

我有什麼,它的工作原理

class AddFriendsController: UIViewController { 

    fileprivate let cellId = "cellId" 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(handleCancel)) 

     let layout = UICollectionViewFlowLayout() 
     layout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10) 
     layout.itemSize = CGSize(width: 111, height: 111) 

     let collectionViewTest = UICollectionView(frame: self.view.frame, collectionViewLayout: layout) 
     collectionViewTest.delegate = self 
     collectionViewTest.dataSource = self 
     collectionViewTest.register(UserFriendCell.self, forCellWithReuseIdentifier: cellId) 

     view.addSubview(collectionViewTest) 
     collectionViewTest.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 
     collectionViewTest.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true 
     collectionViewTest.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true 
     collectionViewTest.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true 
    } 

    @objc private func handleCancel() { 

     self.dismiss(animated: true, completion: nil) 
    } 

} 

extension AddFriendsController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 

    func numberOfSections(in collectionView: UICollectionView) -> Int { 

     return 2 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 

     return 9 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! UserFriendCell 

     return cell 
    } 
} 

我想什麼它是像

class AddFriendsController: UIViewController { 

    fileprivate let cellId = "cellId" 
    private weak var collectionViewTest: UICollectionView? 
    private weak var layout: UICollectionViewFlowLayout? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(handleCancel)) 

     layout = UICollectionViewFlowLayout() 
     layout!.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10) 
     layout!.itemSize = CGSize(width: 111, height: 111) 

     collectionViewTest = UICollectionView(frame: self.view.frame, collectionViewLayout: layout!) 
     collectionViewTest!.delegate = self 
     collectionViewTest!.dataSource = self 
     collectionViewTest!.register(UserFriendCell.self, forCellWithReuseIdentifier: cellId) 

     view.addSubview(collectionViewTest!) 
     collectionViewTest!.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 
     collectionViewTest!.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true 
     collectionViewTest!.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true 
     collectionViewTest!.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true 
    } 

    @objc private func handleCancel() { 

     self.dismiss(animated: true, completion: nil) 
    } 
} 

extension AddFriendsController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 

    func numberOfSections(in collectionView: UICollectionView) -> Int { 

     return 2 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 

     return 9 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! UserFriendCell 

     return cell 
    } 
} 

這樣做是因爲我想嘗試從應用「最佳實踐」開始學習斯威夫特,即從我所瞭解的這種情況下儘可能多的東西privateweak ify /「optionalize」views/outlets,以避免保留c ycles。

問題

應用崩潰,因爲爆炸在layout!.sectionInset水平展開一個零。

任何善良的靈魂願意開導我嗎?

在此先感謝。

+0

爲什麼你佈局屬性弱?它保留視圖控制器嗎?你爲什麼不從聲明中初始化它?所以你不需要強制unwrap:'private let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()' –

回答

2

看起來像你聲稱你佈局爲弱。如果你改變它強壯,即只是刪除弱,那麼你應該沒問題。

同樣適用於您的CollectionView。

同樣作爲一種風格問題,你可以聲明你的佈局和你的collectionView被隱式解開,而不是每次解開包裝。

因此,像private var layout: UICollectionViewFlowLayout!

+0

也可以從collectionView中刪除弱點,當你製作IBOutlet的時候你應該使用弱點,因爲這個視圖被創建並保存在storyboard/xib中! –

+0

作品好@Chris,謝謝! @Vadim確定這是我的主要訊問:'只有在從故事板設計UI時才需要弱視圖視圖,而不是因爲你剛剛引用的原因而不是編程式的,也就是說,在我沒有其他人指出它的情況下它將被安全地釋放?如果我在另一個控制器'controllerB'中引用'collectionViewTest'會怎麼樣:我應該在'controllerB'中弱引用這個引用以避免當我關閉'controllerB'時的保留週期? – Herakleis

0

沒有與你的代碼的問題。

如果你正在服用的變量作爲可選像

private weak var layout: UICollectionViewFlowLayout? 

然後用力才解開你應該確認這是不爲零。所以在這條線上它會導致崩潰,因爲你正在試圖強行解開一個實際上爲零的變量。

layout!.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10) 

因此,如果你想要這樣做,而不添加非零檢查比你應該寫。

layout?.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10) 

但在這裏你的代碼也是錯誤的,因爲,因爲弱引用是隻是一個指向對象,不保護對象由ARC被釋放你不應該採取變量弱。

在這裏你想UICollectionViewFlowLayout和UICollectionView通過了UIViewController的生命週期,所以你不應該把它當成弱。

所以你應該將兩者都定義爲under。

private var collectionViewTest: UICollectionView! 
    private var layout: UICollectionViewFlowLayout! 

OR

private var collectionViewTest: UICollectionView? 
    private var layout: UICollectionViewFlowLayout? 
+0

感謝細節@Nikunj – Herakleis

+0

這是我的榮幸:) –

相關問題