制作 getNotificationSettings return 而不是使用完成块
Making getNotificationSettings return instead of using a completion block
我有一个方法用于我正在开发的应用程序的多个位置。这是一种检查远程推送通知是否启用的方法。方法 return 是一个值,但您可能知道 currentUserNotificationSettings
已被弃用,所以现在我使用 getNotificationSettings
.
问题是第一个 return 是一个值,而最新的使用了一个块。我仍然希望能够 return 一个值以避免重构所有内容,所以我写了以下内容,但它失败了,我不明白为什么...
这样可以吗?!
public static var isRemoteEnabled: Bool {
var notificationSettings: UNNotificationSettings?
let semasphore = DispatchSemaphore(value: 2)
UNUserNotificationCenter.current().getNotificationSettings { setttings in
notificationSettings = setttings
semasphore.signal()
}
semasphore.wait()
guard let authorizationStatus = notificationSettings?.authorizationStatus else { return false }
return authorizationStatus == .authorized
}
已编辑:
我关注了@rmaddy 的评论,至少现在它没有崩溃,但它卡在了 wait()
中。如果我转到调试器并 e semasphore.signal()
它完成并且应用程序继续正常工作。不知何故,完成块没有被调用。
在这种情况下,您希望创建的信号量初始值为 0
,而不是 2
。
let semasphore = DispatchSemaphore(value: 0)
文档中提到了这一点:
Passing zero for the value is useful for when two threads need to reconcile the completion of a particular event.
wait
先递减数值。然后它会阻塞,直到该值大于或等于 0。您的值为 2,它被递减为 1,因为它已经大于或等于 0,所以 wait
不需要阻塞,您的方法在调用 signal
.
之前很久就返回了
还有可能在同一个线程上调用 getNotificationSettings
的完成块(导致死锁),因此在后台队列上调用它。
public static var isRemoteEnabled: Bool {
var notificationSettings: UNNotificationSettings?
let semasphore = DispatchSemaphore(value: 0)
DispatchQueue.global().async {
UNUserNotificationCenter.current().getNotificationSettings { setttings in
notificationSettings = setttings
semasphore.signal()
}
}
semasphore.wait()
guard let authorizationStatus = notificationSettings?.authorizationStatus else { return false }
return authorizationStatus == .authorized
}
我有一个方法用于我正在开发的应用程序的多个位置。这是一种检查远程推送通知是否启用的方法。方法 return 是一个值,但您可能知道 currentUserNotificationSettings
已被弃用,所以现在我使用 getNotificationSettings
.
问题是第一个 return 是一个值,而最新的使用了一个块。我仍然希望能够 return 一个值以避免重构所有内容,所以我写了以下内容,但它失败了,我不明白为什么...
这样可以吗?!
public static var isRemoteEnabled: Bool {
var notificationSettings: UNNotificationSettings?
let semasphore = DispatchSemaphore(value: 2)
UNUserNotificationCenter.current().getNotificationSettings { setttings in
notificationSettings = setttings
semasphore.signal()
}
semasphore.wait()
guard let authorizationStatus = notificationSettings?.authorizationStatus else { return false }
return authorizationStatus == .authorized
}
已编辑:
我关注了@rmaddy 的评论,至少现在它没有崩溃,但它卡在了 wait()
中。如果我转到调试器并 e semasphore.signal()
它完成并且应用程序继续正常工作。不知何故,完成块没有被调用。
在这种情况下,您希望创建的信号量初始值为 0
,而不是 2
。
let semasphore = DispatchSemaphore(value: 0)
文档中提到了这一点:
Passing zero for the value is useful for when two threads need to reconcile the completion of a particular event.
wait
先递减数值。然后它会阻塞,直到该值大于或等于 0。您的值为 2,它被递减为 1,因为它已经大于或等于 0,所以 wait
不需要阻塞,您的方法在调用 signal
.
还有可能在同一个线程上调用 getNotificationSettings
的完成块(导致死锁),因此在后台队列上调用它。
public static var isRemoteEnabled: Bool {
var notificationSettings: UNNotificationSettings?
let semasphore = DispatchSemaphore(value: 0)
DispatchQueue.global().async {
UNUserNotificationCenter.current().getNotificationSettings { setttings in
notificationSettings = setttings
semasphore.signal()
}
}
semasphore.wait()
guard let authorizationStatus = notificationSettings?.authorizationStatus else { return false }
return authorizationStatus == .authorized
}