在嵌套函数中返回布尔值

Posted

技术标签:

【中文标题】在嵌套函数中返回布尔值【英文标题】:Returning bool in nested function 【发布时间】:2016-11-12 19:17:15 【问题描述】:

我想请求一些权限并且想要返回 false,除非所有权限都已被授予。 我收到一个错误: "void 函数中出现意外的非 void 返回值"

但我在所有情况下都返回真/假,有什么问题?

func requestPermissions () -> Bool 
    let types: UIRemoteNotificationType = [.alert, .badge, .sound]
    UIApplication.shared.registerForRemoteNotifications(matching: types)
    let center = UNUserNotificationCenter.current()

    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler:  (videoGranted: Bool) -> Void in
        if (videoGranted) 
            AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeAudio, completionHandler:  (audioGranted: Bool) -> Void in
                if (audioGranted) 
                    center.requestAuthorization(options: [.alert, .badge, .sound])  (notificationGranted:Bool, error) -> Void in
                        if (notificationGranted) 
                            DispatchQueue.main.async 

                                return true
                                print("Video, audio & notifications granted")
                            
                         else 

                            return false
                            print("Rejected notifications")
                        
                    
                else 

                    return false
                    print("Rejected audio")
                
            )
         else 

            return false
            print("Rejected video")
        
    )

任何帮助将不胜感激!谢谢。

另一种答案:

func requestPermissionss (completion: ((Bool, Bool, Bool)->Void)?) 
    let types: UIRemoteNotificationType = [.alert, .badge, .sound]
    UIApplication.shared.registerForRemoteNotifications(matching: types)
    let center = UNUserNotificationCenter.current()

    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler:  (videoGranted: Bool) -> Void in
        AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeAudio, completionHandler:  (audioGranted: Bool) -> Void in
            center.requestAuthorization(options: [.alert, .badge, .sound])  (notificationGranted:Bool, error) -> Void in
                completion?(videoGranted, audioGranted, notificationGranted)
            
        )
    )

【问题讨论】:

else print("Rejected notifications") has no status=true @alldani-com 嗨,我复制了错误的功能,对不起。更新的问题。 在 return 语句之后 swift 是否仍然运行?我知道python没有。 查找“如何从异步函数返回值” 尝试将打印语句放在返回语句之前。 【参考方案1】:

问题是闭包内部return关键字与requestPermissions()函数的返回无关。它的意思是从闭包中返回,实际上并没有返回任何东西(因为-> Void 部分)

您可以像这样将带有三个 bool 参数的闭包传递给您的函数:

func requestPermissions (completion: ((Bool, Bool, Bool)->Void)?) 
    let types: UIRemoteNotificationType = [.alert, .badge, .sound]
    UIApplication.shared.registerForRemoteNotifications(matching: types)
    let center = UNUserNotificationCenter.current()

    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler:  (videoGranted: Bool) -> Void in
        if (videoGranted) 
            AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeAudio, completionHandler:  (audioGranted: Bool) -> Void in
                if (audioGranted) 
                    center.requestAuthorization(options: [.alert, .badge, .sound])  (notificationGranted:Bool, error) -> Void in
                        if (notificationGranted) 
                            completion?(true, true, true)
                         else 
                            completion?(true, true, false)
                        
                    
                else 
                    completion?(true, false, false)
                
            )
         else 
            completion?(false, false, false)
        
    )

用法:

requestPermissions  (videoGranted, audioGranted, notificationsGranted) in
    print("video granted: \(videoGranted)")
    print("audio granted: \(audioGranted)")
    print("notifications granted: \(notificationsGranted)")

请注意,我还删除了DispatchQueue.main.async,因为它在这里没有意义。同样,return 表示 return from the current scope,而不是来自外部函数。

编辑

另外需要注意的是,如果视频权限被拒绝,您的代码将不会请求音频和通知权限。不知道是不是故意的。 如果实际上您需要独立请求所有三件事,我想这是您的情况,您应该使用类似于此的方法:

func requestPermissions() 
    let types: UIRemoteNotificationType = [.alert, .badge, .sound]
    UIApplication.shared.registerForRemoteNotifications(matching: types)

    self.requestVideo  videoGranted in
        print("video granted: \(videoGranted)")
        self.requestAudio  audioGranted in
            print("audio granted: \(audioGranted)")
            self.requestNotifications  notificationsGranted in
                print("notification granted: \(notificationsGranted)")
            
        
    



func requestVideo (completion: ((Bool)->Void)?) 
    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler:  (videoGranted: Bool) -> Void in
        completion?(videoGranted)
    )


func requestAudio (completion: ((Bool)->Void)?) 
    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeAudio, completionHandler:  (audioGranted: Bool) -> Void in
        completion?(audioGranted)
    )


func requestNotifications (completion: ((Bool)->Void)?) 
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound])  (notificationGranted:Bool, error) -> Void in
        completion?(notificationGranted)
    

基本上,您在完成上一个请求后立即请求下一个请求,并且无论之前请求的选择是什么,每个下一个请求都是独立请求的。

【讨论】:

我不知道该怎么说,但如果我这样做,函数将自动返回初始化值 (false)。然后在询问所有权限后,它将返回他们给出的任何内容..【参考方案2】:

您正在尝试在 completionHandler 块中返回 Bool 值,该块的返回类型为 void,您可能显然知道不应该返回任何内容!!!

这就是您遇到此错误的原因“在 void 函数中出现意外的非 void 返回值”

【讨论】:

以上是关于在嵌套函数中返回布尔值的主要内容,如果未能解决你的问题,请参考以下文章

EXCEL函数内部的嵌套函数

python--函数的返回值函数参数的使用名称空间与作用域函数嵌套函数对象

Azure 函数对象返回未返回正确的嵌套值

从Javascript中的嵌套函数返回值[重复]

从Javascript中的嵌套函数返回值[重复]

python中函数嵌套循环语句时,return 如何正确使用返回值