iOS Swift开发中需要注意的问题

  • 普通block和lazy底层是闭包,必须注意self指针泄露,解决方案同block:

    1
    2
    3
    private lazy var oneButtonView : OneButtonView? = {[weak self] in
    return self?.instanceOneButtonView()
    }()
  • 判断字符串相等时必须先校验是否为nil,否则崩溃

    1
    2
    if name != nil && name == "UserName"{
    }
  • 超级坑,View的名字不可于VC相似
    例如:BuyPresellView BuyPresellViewController,会造成BuyPresellViewController自动从BuyPresellView.xib加载;

  • UITextLabel text设置为nil或””时该控件的高度为0,如果想正常显示可设为” “

  • 可选值不可与非可选值进行比较,例如String?和String,必须转换为相同类型才可比较mobile != nil && mobile! == text,注意判断非空;
  • 点击事件触发网络操作,需要用到index时,可使用id替换,防止非阻塞对话框导致用户继续操作,造成index改变;
  • 所有涉及到数组、集合index取值、删除等操作必须校验Index范围保证不会越界;
  • switch中case必须加break,避免养成习惯在其它编程语言中造成问题;
  • 禁止在layoutSubviews编写任何AutoLayout代码,会造成在iOS7.X崩溃;
  • 字符串拼接的时候,如果是可选型必须强制转换,否则string会带Optional字符串;
  • 系统api重写时必须调用super;
  • 添加NSNotification监听的类必须是NSObject的子类,并且响应函数不能使用private修饰,否则崩溃;
  • Objective-C属性或者方法如果不加Nullability属性的话,则默认为隐式可
    选类型。应该声明为可选类型防止空值时造成崩溃;
    如下图所示,AFN成功失败的block中参数应该声明为可选型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    NetworkUtils.getManager().POST("", parameters: nil
    , success: { (operation: AFHTTPRequestOperation?, response:AnyObject?) in
    if response != nil{
    }
    }) { (operation: AFHTTPRequestOperation?, error:NSError?) in
    if error != nil{
    }
    }
  • 为了和 Objective-C 协同工作,很多 Swift 标准库类型和对应的 Cocoa
    类型是可以隐式的类型转换的,比如 Swift.Array 与 NSArray,
    Swift.String 和 NSString 等,类型转换有较大的性能开销,应该避免或减
    少类型转换,尽量使用Swift提供的数据类型;

  • 使用通知,如果是一对一的情况,必须使用EventMsg中标识的唯一时间戳
    校验,防止出现多个页面时,多个页面都收到通知;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // 发送一对一广播
    let scrollType = UICollectionViewDelegateForNavBar.SCROLL_TYPE_DOWN
    let eventMsg = EventMsg(targetEventTime: targetEventTime, object: scrollType)
    NSNotificationCenter.defaultCenter().postNotificationName(UICollectionViewDelegateForNavBar.NOTI_NAME_NAVBAR_SCROLL, object: eventMsg)
    // 处理接收到的广播
    func onNavBarViewScrollNotification(noti:NSNotification){
    if supportNavbarScroll{
    if let eventMsg = noti.object as? EventMsg{
    if eventMsg.targetEventTime == nil || eventMsg.targetEventTime != eventTime{
    return
    }
    if let scrollType = eventMsg.object as? Int{
    navBarViewScrollToTop(scrollType)
    }
    }
    }
    }
  • 对于一次性的vc addsubview,用完之后调用以下函数,不要调用
    self.view.hide = true,应该将该完全销毁,可以使用vc扩张中添加的函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    // 添加ViewController
    func zzAddChildViewController(childVC: UIViewController, anim: Bool = true){
    self.view.addSubview(childVC.view)
    self.addChildViewController(childVC)
    childVC.didMoveToParentViewController(self)
    // anim
    if anim{
    childVC.view.alpha = 0.0
    UIView.animateWithDuration(0.3, animations: {() -> Void in
    childVC.view.alpha = 1.0
    }) { (finished) -> Void in
    }
    }
    }
    // 删除ViewController
    func zzRemoveFromParentViewController(anim: Bool = true){
    if anim{
    UIView.animateWithDuration(0.3, animations: {[weak self] () -> Void in
    self?.view.alpha = 0.0
    }) {[weak self] (finished) -> Void in
    self?.view.hidden = true
    self?.willMoveToParentViewController(nil)
    self?.view.removeFromSuperview()
    self?.removeFromParentViewController()
    }
    }else{
    self.view.hidden = true
    self.willMoveToParentViewController(nil)
    self.view.removeFromSuperview()
    self.removeFromParentViewController()
    }
    }
0%