简体   繁体   English

在Swift中为特定方法调用实现闭包

[英]Implementing closure for specific method call in Swift

I came across the following UITableViewController code and wanted to implement the associated classes and functions that go with them in order for me to learn a little bit more about Swift. 我遇到了以下UITableViewController代码,并希望实现与它们一起关联的classes和函数,以便让我进一步了解Swift。

I'm not sure what the implementation of api.getRooms() looks like. 我不确定api.getRooms()的实现是什么样的。 I think it may be a closure, but I'm not entirely sure? 我认为这可能是一个结局,但我不确定吗?

My question is what would api.getRooms() be returning considering there's {} usage? 我的问题是,考虑到{}用法, api.getRooms()将返回什么? If anyone could explain to me what's going on that would be greatly appreciated. 如果有人可以向我解释发生了什么,那将不胜感激。

api.getRooms(User.currentUser()!) { (roomsObj, error) in
    if let rooms = roomsObj as? Array<Room> {
        self.rooms = rooms
        self.tableView.reloadData()
        if (viaPullToRefresh) {
            self.refreshControl.endRefreshing()
        }
    }
}

PullViewController.swift PullViewController.swift

class PullViewController: UITableViewController {
    var rooms = Array<Room>()

    init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder)

        // Custom initialization
        assert(User.currentUser())
    }

    override func viewDidLoad() {
        self.refreshControl = UIRefreshControl()
        self.refreshControl.addTarget(self, action: Selector("refreshInvoked"), forControlEvents: UIControlEvents.ValueChanged)
        refresh()
    }

    override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
        return rooms.count
    }

    override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath:NSIndexPath!) -> UITableViewCell! {
        var cell: UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell
        if !cell {
            cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier:"Cell")
        }

        let room = rooms[indexPath.row]
        cell!.textLabel.textColor = UIColor.blackColor()
        cell!.textLabel.text = "\(room.name)(\(room.messageCount))"
        return cell
    }

    func refreshInvoked() {
        refresh(viaPullToRefresh: true)
    }

    func refresh(viaPullToRefresh: Bool = false) {
        let api = API()
        api.getRooms(User.currentUser()!) { (roomsObj, error) in
            if let rooms = roomsObj as? Array<Room> {
                self.rooms = rooms
                self.tableView.reloadData()
                if (viaPullToRefresh) {
                    self.refreshControl.endRefreshing()
                }
            }
        }
    }
}

User.swift User.swift

class User {

    init() {
    }

    class func currentUser() -> Bool {
        return true
    }
}

Room.swift Room.swift

class Room {

    var name: String
    var messageCount: Int

    init() {
    }
}

API.swift (not sure whether this is implemented correctly). API.swift (不确定是否正确实现)。

class API {

    init() {
    }

    func getRooms(user: User) -> (Array<Room>, String) { // ??
        // ??
    }
}

1) You are sending assert a void since your currentUser method doesn't return anything, so assert wouldn't know if this is good or bad. 1)您正在发送断言,因为您的currentUser方法不返回任何内容,因此断言将不知道这是好是坏。 Therefore you need to make currentUser return a BOOL or something else if you want to use it like this, but it needs some sort of BOOL result to tell if it is asserting correctly or not. 因此,如果要像这样使用currentUser,则需要让currentUser返回BOOL或其他内容,但是它需要某种BOOL结果来判断其是否正确断言。 Hopefully that makes sense. 希望这是有道理的。

2)You are trying to feed your getRooms function a lambda function instead of running a function after the results. 2)您尝试将getRooms函数提供给lambda函数,而不是在结果之后运行函数。

--Update-- If you are wanting a completion lambda then you'll want to write getRooms like this: -更新-如果您想要一个完成lambda,那么您将需要编写如下的getRooms:

func getRooms(user: User, completion: ((Array<Room>,String?) -> Void)?) -> Array<Room> {//String because I have no idea what type they want for errors
    var room = Room()

    room.messageCount = 0
    room.name = "Room1"

    var rooms = Array<Room>()
    rooms.append(room)

    completion?(rooms,nil)

    return rooms
}

or something along those lines 或类似的规定

In you room class, you did not initialize the name and message count variable, in swift only optional variable can be nil 在您的会议室类中,您没有初始化名称和消息计数变量,因此迅速只有可选变量可以为nil

class Room {

    var name: String
    var messageCount: Int

    init(name:String, messageCount:Int) {
        self.name = name
        self.messageCount = messageCount
    }
}

also assert need to evaluate to bool so 还断言需要评估为布尔

assert(User.currentUser() != nil)

This is how I implemented the api.getRooms() function: 这就是我实现api.getRooms()函数的方式:

API.swift API.swift

class API {

    func getRooms(user: User, completion: (Array<Room>, String) -> ()) {
        var room = Room(name: "Room1", messageCount: 0)

        var rooms = Array<Room>()
        rooms.append(room)

        completion(rooms, "error")
    }

}

PullViewController.swift PullViewController.swift

func refresh(viaPullToRefresh: Bool = false) {

    let api = API()

    if let user = User.currentUser() {
        api.getRooms(user) { (roomsObj, error) in
            self.rooms = roomsObj
            self.tableView.reloadData()
            if (viaPullToRefresh) {
                self.refreshControl.endRefreshing()
            }
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM