2017-02-16 53 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

这是我的荣幸:) –

相关问题