在 Swift 中为特定方法调用实现闭包
Posted
技术标签:
【中文标题】在 Swift 中为特定方法调用实现闭包【英文标题】:Implementing closure for specific method call in Swift 【发布时间】:2014-06-17 06:19:41 【问题描述】:我遇到了以下 UITableViewController
代码,并想实现相关联的 classes
和与之配套的函数,以便我了解更多关于 Swift 的知识。
我不确定api.getRooms()
的实现是什么样的。我认为这可能是一个关闭,但我不完全确定?
我的问题是,考虑到 的使用情况,
api.getRooms()
会返回什么?如果有人能向我解释发生了什么,将不胜感激。
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
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
class User
init()
class func currentUser() -> Bool
return true
Room.swift
class Room
var name: String
var messageCount: Int
init()
API.swift (不确定这是否正确实现)。
class API
init()
func getRooms(user: User) -> (Array<Room>, String) // ??
// ??
【问题讨论】:
您不需要在 Swift 中的 Selector() 中包装选择器,只需提供带引号的目标方法名称(其中尾随 ':' 字符 = 参数占位符,没有 ':' = 没有参数目标函数) 【参考方案1】:在你的房间类中,你没有初始化 name 和 message count 变量,在 swift 中只有可选变量可以是 nil
class Room
var name: String
var messageCount: Int
init(name:String, messageCount:Int)
self.name = name
self.messageCount = messageCount
还断言需要评估为布尔所以
assert(User.currentUser() != nil)
【讨论】:
感谢您的回答。assert()
现在有意义了。只是想知道api.getRooms()
这个函数现在是怎么实现的。
在init完成前需要设置name和mesageCount,可以在init中设置或者使用可选变量var name:String?【参考方案2】:
1) 您正在发送 assert 一个 void ,因为您的 currentUser 方法不返回任何内容,因此 assert 不知道这是好是坏。因此,如果你想像这样使用它,你需要让 currentUser 返回一个 BOOL 或其他东西,但它需要某种 BOOL 结果来判断它是否正确断言。希望这是有道理的。
2)您试图为您的 getRooms 函数提供一个 lambda 函数,而不是在结果之后运行一个函数。
--更新-- 如果你想要一个完成 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
或者类似的东西
【讨论】:
这对于assert()
来说非常有意义。 getRooms()
函数。我必须阅读有关 Swift 中的 lambda 的内容,看看如何才能实现与此代码一起工作的一个。
我猜对了你的意图吗?如果是这样,您可以添加一个可选的 lambda 参数来获取房间。
希望这个例子有点帮助
这实际上很有帮助并且非常有意义,但是我必须在 completion:
之前添加一个逗号,并且在 ?callback? completion()
方法说:Cannot convert the expression's type '$T3' to type '(Array<Room>, String?)?'
从函数中删除?
's 然后抛出这个错误:'(@lvalue Array<Room>, $T2) -> $Y3 'is not identical to '(Array<Room>, String)'
【参考方案3】:
这就是我实现api.getRooms()
函数的方式:
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
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()
【讨论】:
以上是关于在 Swift 中为特定方法调用实现闭包的主要内容,如果未能解决你的问题,请参考以下文章