performSelectorOnMainThread 的 Swift 替代方案
Posted
技术标签:
【中文标题】performSelectorOnMainThread 的 Swift 替代方案【英文标题】:Swift alternative to performSelectorOnMainThread 【发布时间】:2014-06-09 18:12:46 【问题描述】:我想用这个方法在一个块中重新加载我的表数据:
import UIKit
import AssetsLibrary
class AlbumsTableViewController: UITableViewController
var albums:ALAssetsGroup[] = []
func loadAlbums()
let library = IAAssetsLibraryDefaultInstance
library.enumerateGroupsWithTypes(ALAssetsGroupType(ALAssetsGroupAll),
usingBlock: (group, stop) in
if group
self.albums.append(group)
else
dispatch_async(dispatch_get_main_queue(),
self.tableView.reloadData()
)
, failureBlock: (error:NSError!) in println("Problem loading albums: \(error)") )
override func viewDidLoad()
super.viewDidLoad()
loadAlbums()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
//self.navigationItem.rightBarButtonItem = self.editButtonItem
但是 else 块不会执行。我得到的错误是:
'performSelectorOnMainThread' is unavailable: 'performSelector' methods are unavailable
那么 swift 中'performSelectorOnMainThread'
的替代方法是什么?
更新:
我现在遇到中止错误。
【问题讨论】:
GCD 在 Objective-C 中一直优于performSelectorOnMainThread
有一段时间了,请在此处查看文档:developer.apple.com/library/ios/documentation/Performance/…
【参考方案1】:
这个简单的 C 函数:
dispatch_async(dispatch_get_main_queue(),
// DO SOMETHING ON THE MAINTHREAD
self.tableView.reloadData()
)
如何启动你的函数:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
loadAlbums()
)
在 viewDidLoad() 中?
【讨论】:
不客气。请将答案标记为您的正确答案,以便其他人立即看到答案:) 我说得太早了 - 我现在遇到一个我什至不知道如何调试的错误:cl.ly/image/1d272E263V2N - 请看一下 当异常发生时你在控制台日志中看到了什么(异常只是表示调用了 abort()) 我在自己的项目中尝试过这个,还寻找了 performOnThrad 方法,它们都已被弃用.. 我在表格视图中遇到了可调整大小的单元格的问题,它会根据它是否有缩略图来调整大小,并且它在除 iPhone 6 Plus 之外的每台设备上都能完美运行,但它也能完美运行!谢谢!【参考方案2】:斯威夫特 3
DispatchQueue.main.async(execute:
//Code to execute on main thread
)
【讨论】:
【参考方案3】:使用 GCD 代替 performSelector 变体。
dispatch_async(dispatch_get_main_queue())
() -> Void in
self.doSomething()
【讨论】:
【参考方案4】:你在 UIViewController 上调用 performSelectorOnMainThread 而不是 UITableView 的对象
可能是你的代码:
self.performSelectorOnMainThread(Selector(reloadData), withObject: self.tblMainTable, waitUntilDone: true)
代替:
self.tblMainTable.performSelectorOnMainThread(Selector("reloadData"), withObject: nil, waitUntilDone: true)
您收到该消息是因为 UIViewController 没有任何名为“performSelectorOnMainThread”的方法
【讨论】:
【参考方案5】://Xcode 8.2 // swift 3.0
我正在访问一个 API,该 API 在提交任何城市的名称或邮政编码后提供有关天气的数据,即“温度”、“湿度”、“压力”等。 因此,需要在 UI(tableView)上显示该数据(它必须在主线程上)
self.performSelector(onMainThread: #selector(Home.DataOnUI), with: nil, waitUntilDone: true)
//
func DataOnUI()
self.tblView.reloadData()
附: Home是UIViewController的类
【讨论】:
请用几句话描述您的解决方案。【参考方案6】:Swift 3 / Xcode 8.2
这是一种 Swift 3 的做事方式。只需插入您希望代码在其后执行的时间(以秒为单位)。
let delayTime = DispatchTime.now() + Double(Int64(20.0 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: delayTime)
//Your code to run after 20 seconds
或者,您可以简单地将时间延迟放在单行符号中,如下所示:
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0)
// Your code to run after 10 seconds
【讨论】:
以上是关于performSelectorOnMainThread 的 Swift 替代方案的主要内容,如果未能解决你的问题,请参考以下文章