Swift:将数据传递给捕获上下文的闭包 [英] Swift: Pass data to a closure that captures context

查看:82
本文介绍了Swift:将数据传递给捕获上下文的闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在互联网连接恢复并且 updateOnConnection 变量为true时调用函数。这是我的代码:

  func checkForConnection(){
let host =reddit.com
var context = SCNetworkReachabilityContext(version:0,info:nil,retain:nil,release:nil,copyDescription:nil)
let reachability = SCNetworkReachabilityCreateWithName(nil,host)!

如果flags.rawValue == 0,则
中的SCNetworkReachabilitySetCallback(可达性,{(_,flags,_))// {//未连接互联网

} else { // internet connected connected
if self.updateOnConnection {
self.refreshWallpaper()
}
}
},& context)

SCNetworkReachabilityScheduleWithRoLoop(reachability,CFRunLoopGetMain(),kCFRunLoopCommonModes)
}

我的问题是行:

  if self.updateOnConnection {
self.refreshWallpaper()
}

导致错误: AC函数指针不能从捕获上下文的闭包形成



我不知道如何检查 updateOnConnection 的状态,并调用 refreshWallpaper()在闭包中监视互联网连接的变化。如何解决这个问题,或者有一个完全不同的解决方法,我应该使用?

解决方案 http://stackoverflow.com/questions/33260808/swift-proper-use-of-cfnotificationcenteraddobserver-w-callback\">Swift - 正确使用CFNotificationCenterAddObserver w /回调,您必须转换
self 到一个void指针,将其存储在上下文中,
并将其转换回闭包中的一个对象指针:

  func checkForConnection(){

let host =reddit.com
var context = SCNetworkReachabilityContext :nil,retain:nil,release:nil,copyDescription:nil)
context.info = UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque())

let reachability = SCNetworkReachabilityCreateWithName ,主机)!

如果flags.rawValue == 0,则
中的SCNetworkReachabilitySetCallback(可达性,{(_,flags,info))// {//未连接互联网

} else { // internet已连接
let mySelf = Unmanaged< ViewController> .fromOpaque(COpaquePointer(info))。takeUnretainedValue()

如果mySelf.updateOnConnection {
mySelf.refreshWallpaper
}
}
},& context)

SCNetworkReachabilityScheduleWithRoLoop(reachability,CFRunLoopGetMain(),kCFRunLoopCommonModes)
}

另请参阅如何将self转换为UnsafeMutablePointer< Void>请键入swift
以了解有关此机制的更多详细信息。



备注: if flags .rawValue == 0 可以表示稍微多一些
优雅为如果flags.isEmpty ,但实际上<如果flags.contains(.Reachable)。






更新Swift 3(Xcode 8 beta 6):

  func checkForConnection(){

let host =reddit.com
var context = SCNetworkReachabilityContext(version:0,info:nil,retain:nil,release:nil,copyDescription:nil)
context.info = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())

let reachability = SCNetworkReachabilityCreateWithName(nil,host)!


中的SCNetworkReachabilitySetCallback(reachability,{(_,flags,info)如果let info = info {
if flags.rawValue == 0 {// internet is not connected

} else {// internet become connected
let mySelf = Unmanaged< ViewController> .fromOpaque(info).takeUnretainedValue()
// ...
}
}
},& context)

SCNetworkReachabilityScheduleWithRunLoop(reachability,CFRunLoopGetMain(),CFRunLoopMode.commonModes.rawValue)
}


I am trying to call a function when the internet connection is restored and the updateOnConnection variable is true. Here is my code:

func checkForConnection() {
    let host = "reddit.com"
    var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
    let reachability = SCNetworkReachabilityCreateWithName(nil, host)!

    SCNetworkReachabilitySetCallback(reachability, { (_, flags, _) in
        if flags.rawValue == 0 { //internet is not connected

        } else { //internet became connected
            if self.updateOnConnection {
                self.refreshWallpaper()
            }
        }
    }, &context)

    SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes)
}

My problem is that the lines:

        if self.updateOnConnection {
            self.refreshWallpaper()
        }

cause the error: "A C function pointer cannot be formed from a closure that captures context"

I am not sure how to check the state of updateOnConnection and call refreshWallpaper() in the closure that monitors changes in the internet connection. How can I fix this, or is there a totally different workaround I should be using?

解决方案

Similar as in Swift - Proper use of CFNotificationCenterAddObserver w/callback, you have to convert self to a void pointer, store that in the context, and convert it back to an object pointer in the closure:

func checkForConnection() {

    let host = "reddit.com"
    var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
    context.info = UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque())

    let reachability = SCNetworkReachabilityCreateWithName(nil, host)!

    SCNetworkReachabilitySetCallback(reachability, { (_, flags, info) in
        if flags.rawValue == 0 { //internet is not connected

        } else { //internet became connected
            let mySelf = Unmanaged<ViewController>.fromOpaque(COpaquePointer(info)).takeUnretainedValue()

            if mySelf.updateOnConnection {
                mySelf.refreshWallpaper()
            }
        }
        }, &context)

    SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes)
}

See also How to cast self to UnsafeMutablePointer<Void> type in swift for more details about this mechanism.

Remark: if flags.rawValue == 0 can be expressed slightly more elegant as if flags.isEmpty, but what you actually should check is if flags.contains(.Reachable).


Update for Swift 3 (Xcode 8 beta 6):

func checkForConnection() {

    let host = "reddit.com"
    var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
    context.info = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())

    let reachability = SCNetworkReachabilityCreateWithName(nil, host)!

    SCNetworkReachabilitySetCallback(reachability, { (_, flags, info) in
        if let info = info {
            if flags.rawValue == 0 { //internet is not connected

            } else { //internet became connected
                let mySelf = Unmanaged<ViewController>.fromOpaque(info).takeUnretainedValue()
                // ...
            }
        }
    }, &context)

    SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), CFRunLoopMode.commonModes.rawValue)
}

这篇关于Swift:将数据传递给捕获上下文的闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆