Swift专题iOSiOS 传值

通知, 代理, block的数据传递

2016-06-01  本文已影响497人  iYeso

通常我们实现的数据传递方式有:

1. 通知

- 1.1 通知 使用方法

1.  添加监听通知       
      NSNotificationCenter.defaultCenter().addObserver(<#T##observer: AnyObject##AnyObject#>, selector: <#T##Selector#>, name: <#T##String?#>, object: <#T##AnyObject?#>)
    
2.  添加发送通知
      NSNotificationCenter.defaultCenter().postNotificationName(<#T##aName: String##String#>, object: <#T##AnyObject?#>)

3.  移除通知
      NSNotificationCenter.defaultCenter().removeObserver(<#T##observer: AnyObject##AnyObject#>)

- 1.2 通知 使用场景

    1. 当我们的view嵌套很深的时候, 这样我们无论使用代理还是block都将非常的麻烦.
    2. 两个控制器之间没有什么必然的联系

- 1.3通知 使用缺点

    1. 不利于我们维护我们的代码(添加通知和发送通知没有必然联系, 不像代理和block那样数据间有必然的联系)
    2. 效率较低
    3. 需要设置移除通知的方法(我经常忘记)

2. 代理

- 2.1 使用方法

 记住使用代理就是 6个步骤就可以了!
 1. 声明协议
 2. 设置代理属性
 3. 通知代理
 4. 遵守协议
 5. 设置成为代理
 6. 实现代理

还是swift代码 代理的实现

 // 1. 定义协议
@objc protocol ZXZPictureSelectorCellDelegate: NSObjectProtocol {
         //定义协议方法
       optional func userWillAddPicture()
       optional func userWillDeletePicture(cell: HMPictureSelectorCell)
 }


// 2. 代理对象的属性  要使用 weak 表示弱引用
weak var selectorDelegate: ZXZPictureSelectorCellDelegate?


// 3.  通知代理
selectorDelegate?.userWillAddPicture?()

// 4. 遵守协议
extension HMPictureSelectorController: HMPictureSelectorCellDelegate{
} 


// 5.  设置成为代理
 cell.selectorDelegate = self

// 6. 实现代理
 func userWillAddPicture() { /*内容就不贴了*/ }
 func userWillDeletePicture(cell: ZXZPictureSelectorCell) {/*内容就不贴了*/ }

- 2.2 使用场景

 1. 两者相对之间有一定的关联
 2. 代理最常用的是反向传值!!!通知某个属性发生改变,让代理去实现!还有就是解耦!!!

- 2.3 使用缺点

1. 相对于block稍微麻烦一点(吹毛求疵了)
2. 当两者没有必然的联系 无法实现数据传递 

3. block

- 3.1 使用方法

 针对block的使用不想说太细 直接上代码, 改天我会总结block的用法  有需要的可以关注一下,
 因为最近正在学习swift 我就贴上我swift单例封装的AFNetworking吧


 class AFNetworkingTools: AFHTTPSessionManager {

//MARK: 声明一个单例对象
static let shareTools:AFNetworkingTools = {
    let tools = AFNetworkingTools(baseURL: nil)
    tools.responseSerializer.acceptableContentTypes?.insert("text/plain")
    return tools
}()


 // MARK: - 封装POST和Get请求
func request(methods:HTTPMethods, urlString:String, parameters: [String:AnyObject]?, finash:((success: AnyObject?, error:NSError?) -> ()) ){

    if methods == .GET {
        GET(urlString, parameters: parameters, progress: nil, success: { (task, result) in
            finash(success: result, error: nil)

            }, failure: { (task, error) in
                finash(success: nil, error: error)
        })
    }else{
        POST(urlString, parameters: parameters, progress: nil, success: { (task, result) in
            finash(success: result, error: nil)

            }, failure: { (task, error) in
                finash(success: nil, error: error)
        })
    }
}

}

 我们对我们单例中疯装的block代码块进行调用   
 AFNetworkingTools.shareTools.request(HTTPMethods.GET, urlString: urlString, parameters: parama) { (success, error) in
        if error != nil{
            print("我们获取个人数据失败")
            return
        }

        print("成功获取数据: ", success)
   }

- 3.2 使用场景

 两者有必然的关联的情况下 我们就可以实现block的回调实现数据传递
 在我们的工作中要多使用block, block的使用有利于我们的维护代码. 
 而且使用也是最方便的(但是注意block引用循环的问题!!)
 反向传值!!!通知某个属性发生改变,让代理去实现!还有就是解耦!!!

- 3.3 使用缺点

 如果没有关联 数据将无法实现数据传递

以上是我个人理解 可能存在很多问题 还望大家多多指教! 如果有任何疑问还望大家留言,大家互相探讨 还望大家多多鼓励!!多多批评

上一篇下一篇

猜你喜欢

热点阅读