【问题标题】:How to pass a completion block to another class in Swift如何将完成块传递给 Swift 中的另一个类
【发布时间】:2016-06-05 22:42:59
【问题描述】:

在 Objective-C 中,我使用了现在必须转换为 Swift 的完成块的这种处理方式:

DetailDisplayController.h

typedef void (^AddedCompletitionBlock)(BOOL saved, NSString *primarykey, NSUInteger recordCount);

@interface DetailDisplayController : UITableViewController

@property (nonatomic, copy) AddedCompletitionBlock completionBlock;
@property (strong, nonatomic) Details *detail;

DetailDisplayController.m

- (void) saveClicked:(id)sender
{  
   // retrieve PK
   NSString *objectId = [[[_detail objectID] URIRepresentation] absoluteString];

   if (self.completionBlock != nil)
   {
       self.completionBlock(_rowChanged, objectId, [_fetchedResultsController.fetchedObjects count]);
   }

_rowChanged 和 _fetchedResultsController 是实例变量

并且在 DetailViewController.m 调用类中,使用了传递的块

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
   if ([segue.identifier isEqualToString:@"DetailDisplay"])
   {
       DetailDisplayController *detailDisplayController = segue.destinationViewController; 
       ...
       detailDisplayController.completionBlock = ^(BOOL saved, NSString *sorter, NSUInteger recordCount)
       {
        if (saved)
           ...

如何在 Swift 中做到这一点?

【问题讨论】:

  • Swift 中的函数可以像变量一样传递。
  • 好的,我可以从调用类传递一个函数。但是如何共享被调用类中的变量呢?
  • 请展示您正在尝试做的事情以及解决方案的尝试(在 Swift 中)。
  • 抱歉垫片,没有什么可显示的,因为我不知道如何开始 :-( 我只是在谷歌上搜索解决方案。同时我认为,我的 Swift 知识太差,无法解决这……

标签: swift block


【解决方案1】:

这是您在 Swift 中需要的等效部分:

typealias AddedCompletionBlock = (saved: Bool, primaryKey: String, recordCount: Int) -> Void

var completionBlock: AddedCompletionBlock? = nil

completionBlock = {saved, primaryKey, recordCount in
    print("\(saved), \(primaryKey), \(recordCount)")
}

completionBlock?(saved: true, primaryKey: "key", recordCount: 1)

您可能想好好阅读 Apple Swift 文档的 "Function Types""Closures" 部分。

【讨论】:

  • 嗨,伊万,很多 THX,就是这样。我只需要将“completionBlock = {saved, primaryKey, recordCount in”这一行移到我的 DetailViewController.m... 而且我不需要阅读任何内容,我都明白了 ;-)
【解决方案2】:

在 Swift 中,补全非常简单。这是一个例子。我按下按钮打开 SecondVC,然后按下 SecondVC 上的按钮将其关闭,然后调用完成,它将更改 FirstVC 上的标签:

    class ViewController: UIViewController {
    @IBOutlet weak var label: UILabel!

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

    @IBAction func didTapButton(_ sender: Any) {
        let vc = storyboard?.instantiateViewController(withIdentifier: "SecondVC") as! SecondVC
        self.present(vc, animated: true, completion: nil)
        vc.completion = { str in
            self.label.text = str
        }
    }
 }

这就是 SecondVC 的样子:

 class SecondVC: UIViewController {
    var completion:((String)->())?

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

    @IBAction func didTapButton(_ sender: Any) {
        completion?("Hello")
        self.dismiss(animated: true, completion: nil)
    }
}

【讨论】:

    猜你喜欢
    • 2021-11-09
    • 2015-12-03
    • 2012-07-04
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多