Swift 用Delegate和Block实现回调的Demo

一、有关回调

我们知道,执行函数的时候,一般都有return作为返回参数了,那有return了为什么还要回调呢?

回调是为了实现异步的返回,在某些特殊的情况下,比如你执行的函数是一个长时间运行的函数,并不能直接返回给你结果,为了不影响源程序其他步骤的执行,你得继续执行下去,等那边产生结果了再“主动告诉你”结果是什么。

(我考虑了一下,如果使用多线程+return的方式,也许也是能够实现异步的,但并不是万能的,因为子线程中不能做UI处理)

在iOS开发中,实现回调的方式有:Delegate和Block。前者用变量指针实现,后者用函数指针实现。

假如我现在有一个processData的类用来处理数据,处理完之后回调给主要的Class。

二、Swift中实现回调

1.代理模式:利用protocol+引用变量

processData.swift

//
//  ProcessData.swift

import UIKit
//定义协议
protocol callBackDelegate {
    func callbackDelegatefuc(backMsg:String)
}

class ProcessData: NSObject{
    //定义一个符合改协议的代理对象
    var delegate:callBackDelegate?
    func processMethod(cmdStr:String?){
        if((delegate) != nil){
            delegate?.callbackDelegatefuc("backMsg---by delegate")
        }
    }
}

ViewController.swift

//
//  ViewController.swift

import UIKit

//继承该协议
class ViewController: UIViewController,callBackDelegate{

    override func viewDidLoad() {
        super.viewDidLoad()
        let process=ProcessData()

        //把process的delegate变量指针指向自己,那样process就能调用自己类里的函数了
        process.delegate=self

        //执行函数
        process.processMethod("startProcess")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    //delegate回调
    func callbackDelegatefuc(backMsg:String){
        print(backMsg)
    }
}

2.利用闭包实现:

闭包在Objective-C中被称为Block,在Swift中被成为Closure(在Java中称为Lambda)

2.1利用闭包变量实现回调

processData.swift

//
//  ProcessData.swift

import UIKit

class ProcessData: NSObject{
    //定义block
    typealias fucBlock = (backMsg :String) ->()
    //创建block变量
    var blockproerty:fucBlock!

    func processMethod(cmdStr:String?){
        if let _ = blockproerty{
            blockproerty(backMsg: "backMsg---by block property")
        }
    }
}

ViewController.swift

//
//  ViewController.swift

import UIKit

class ViewController: UIViewController{

    override func viewDidLoad() {
        super.viewDidLoad()
        let process=ProcessData()

        //block回调
        process.blockproerty={ (backMsg) in
            print(backMsg)
        }

        //执行函数
        process.processMethod("processStart")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

2.2 把闭包写入函数作参数实现快速回调,可见这是一种代码最为简洁的方案

processData.swift

//
//  ProcessData.swift

import UIKit

class ProcessData: NSObject{
    //定义block
    typealias fucBlock = (backMsg :String) ->()

    func processWithBlock(cmdStr:String?,blockProperty:fucBlock){
        blockProperty(backMsg :"backMsg---by block inside func")
    }
}

ViewController.swift

//
//  ViewController.swift

import UIKit

class ViewController: UIViewController{

    override func viewDidLoad() {
        super.viewDidLoad()
        let process=ProcessData()

        //函数内回调
        process.processWithBlock("bbb") { (backMsg) in
            print(backMsg)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

PS:如果Block带返回值的情况下,Block是这样定义和调用的

//定义block
    typealias fucBlock = (backMsg :String) ->(String)
//函数内回调
        process.processWithBlock("bbb") { (backMsg) ->(String) in
            print(backMsg)
            return "get msg"
        }

swift:https://github.com/rayshen/SwiftClosure

oc:https://github.com/rayshen/callbackDemo

时间: 2024-10-06 01:43:05

Swift 用Delegate和Block实现回调的Demo的相关文章

iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例)

iOS页面间传值的方式(NSUserDefault/Delegate/NSNotification/Block/单例) 实现了以下iOS页面间传值:1.委托delegate方式:2.通知notification方式:3.block方式:4.UserDefault或者文件方式:5.单例模式方式:6.通过设置属性,实现页面间传值 在iOS开发中,我们经常会遇到页面间跳转传值的问题,现归纳总结一下: 情况1:A页面跳转到B页面 方法: 在B页面的控制器中,编写对应的属性,在A页面跳转到B页面的地方,给

iOS页面间传值的五种方式总结(Delegate/NSNotification/Block/NSUserDefault/单例)

iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例) iOS页面间传值的方式(NSUserDefault/Delegate/NSNotification/Block/单例) 实现了以下iOS页面间传值:1.委托delegate方式:2.通知notification方式:3.block方式:4.UserDefault或者文件方式:5.单例模式方式:6.通过设置属性,实现页面间传值 在iOS开发中,我们经常会遇到页面间跳转传值的问题,

iOS页面间传值的方式(NSUserDefault/Delegate/NSNotification/Block/单例)

实现了以下iOS页面间传值:1.委托delegate方式:2.通知notification方式:3.block方式:4.UserDefault或者文件方式:5.单例模式方式:6.通过设置属性,实现页面间传值 在iOS开发中,我们经常会遇到页面间跳转传值的问题,现归纳总结一下: 情况1:A页面跳转到B页面 方法: 在B页面的控制器中,编写对应的属性,在A页面跳转到B页面的地方,给B的属性赋值即可 //SecondViewController.h @property(nonatomic) NSInt

iOS通讯模式(KVO、Notification、Delegate、Block、Target-Action的区别)

文章翻译自 https://www.objc.io/issues/7-foundation/communication-patterns/ 每个Application或多或少都有一些松耦合的对象(模块)组成,他们必须彼此通讯来完成工作.这篇文章将会通过可用的通讯机制,并以Apple的Framework来举例,并给出最佳的实践建议关于使用哪种通讯机制. 虽然这个问题是关于Foundation框架的,但是我们可以通过Foundation的通讯机制,差不多有这几个通讯方法 - KVO,Notifica

iOS页面间传值的方式 (Delegate/NSNotification/Block/NSUserDefault/单例)

iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例) iOS页面间传值的方式(NSUserDefault/Delegate/NSNotification/Block/单例) 实现了以下iOS页面间传值: 1.委托delegate方式:2.通知notification方式:3.block方式:4.UserDefault或者文件方式:5.单例模式方式:6.通过设置属性. 在iOS开发中,我们经常会遇到页面间跳转传值的问题,现归纳总结一

利用block完成回调,小demo一个

利用block完成回调,小demo一个.闲话少说,直接上代码了!O(∩_∩)O~ TestObject.h #import <Foundation/Foundation.h> typedef void (^FinishBlock)(NSString *backStr); @interface TestObject : NSObject //能进行回调的方法 - (void)playSomeTime:(FinishBlock)block; @end TestObject.m #import &q

delegate 和 block 的区别

此文章结合实际的例子很详细的讲解了什么时候适合用delegate 或 block ,此文章不太适合不太熟悉block编程的读者 http://stablekernel.com/blog/blocks-or-delegation/ 下面一边文章是实际的例子用block的方式实现UIAlertView http://www.abdus.me/ios-programming-tips/uialertview-with-blocks-call-back/

IOS开发- 用block实现回调

在IOS开发中经常会用到回调的情况,下面介绍如何用block实现回调. 1 #import <Foundation/Foundation.h> 2 3 @interface BLock : NSObject 4 5 + (void)getBlock:(void (^)(NSString *))someblock; 6 7 @end BLock.h 1 #import "BLock.h" 2 #import <Foundation/Foundation.h> 3

iOS 传值 委托(delegate)和block 对比

 技术交流新QQ群:414971585 这篇文章建议和前一篇一起看, 另外先弄清楚IOS的block是神马东东. 委托和block是IOS上实现回调的两种机制.Block基本可以代替委托的功能,而且实现起来比较简洁,比较推荐能用block的地方不要用委托. 本篇的demo和前一篇是同一个,可以到github上下载不同的版本, 源码下载地址: https://github.com/pony-maggie/DelegateDemo A类(timeControl类)的头文件先要定义block,代码如下