我发现有几篇帖子询问如何运行后台任务。这可以。我得到它。Apple有一个指南,仅适用于某些类型的应用程序。
我的用例如下:我只想在聊天应用程序位于前台时更新该应用程序的联系人列表。因此,当应用程序分别处于以下状态时,我可以启动/暂停/恢复:didBegan、didEnterBackground、didResumeFromBackground。
我如何使用 GCD 来实现这一目标?
换句话说,我如何以重复的方式安排异步任务并且仅每隔一段时间(例如每 0.5 秒)调用一次?有没有使用 NSOperationQueue 的好的实现?
编辑2:我想要执行的任务:
1:从 Web 服务 API 获取包含联系人信息的 JSON 数据对象(在线状态、设备、上次查看时间)
2:从 Web 服务 API 获取包含给用户的消息的 JSON 数据对象
编辑: NSOperation 文档将操作定义为只能用作“单次”的操作,因此创建递归操作可能不是解决此问题的最佳方法。
iphone objective-c nsoperationqueue grand-central-dispatch ios
我的 ViewController 的星级评级如下所示(除了有 10 颗星)
当用户打开 ViewController 来查看某些没有评级的对象时,我想用非常简单的方法将用户的注意力吸引到这些星星上:动画星星突出显示(当每个字母相继突出显示时,您可以在现实世界中的某些广告上看到这种行为)。
这就是我的做法
func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
completion()
}
}
func ratingStarsAnimation() {
for i in 1...11 {
var timer : Double = 0.6 + Double(i)*0.12
delayWithSeconds(timer) {
ratingStars.rating = (i < 10) ? Double(i) : 0
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?我有一个名为delayWithSeconds 的函数来延迟操作,我使用这个函数来延迟每个星星的突出显示。0.6 是动画开始前的初始延迟。突出显示所有星星后 - 最后一步是关闭所有星星的突出显示。这段代码可以工作,但我不能说它很顺利。
我的问题是:
我使用 Firebase 上传带有进度指示器的文件:
RappleActivityIndicatorView.setProgress(CGFloat(a), textValue: "\(String(a * 100)) %")
print("\(a) %")
Run Code Online (Sandbox Code Playgroud)
我想实现一个条件:如果 % 的值(例如:23%)停留 15 秒或更长时间,则会取消上传。
我正在考虑一个 GCD 计时器:
DispatchQueue.main.asyncAfter(deadline: .now() + 15) {
print("We can launch the cancellation of the upload")
}
Run Code Online (Sandbox Code Playgroud)
但我不知道如何链接 a 值在 15 秒内未更新的条件。任何想法 ?
多谢,
class ViewController: UIViewController {
override func viewDidLoad() {
// Do any additional setup after loading the view.
DispatchQueue.main.sync { //this line crashes with Thread 1 : EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
print("Rohit Kumar")
}
}
}
Run Code Online (Sandbox Code Playgroud)
在 viewDidLoad 中使用同步方法崩溃,但它适用于异步,我不知道这背后的原因,任何人都可以帮助我。
我知道同步和异步之间的区别。
我正在尝试从我的 API 加载自定义数据类型并将其显示在我的 iOS 应用程序登录页面上。
据我了解,我应该这样称呼:
override func viewDidLoad() {
performSelector(inBackground: #selector(fetchJSON), with: nil)
let myCustomDataType = //how so I get this back
tableView.reloadData()
//...
}
Run Code Online (Sandbox Code Playgroud)
显然 fetchJSON 的声明应该在另一个文件中,所以我不会用它不需要做的事情来填充我的控制器。但是,我需要此函数来返回 [MyCustomDataType] 列表并将其显示在我的登录页面上。
func fetchJSON() -> [MyCustomDataType] {
//get api, fetch data, put it in my custom data type list
return myCustomDataType
}
Run Code Online (Sandbox Code Playgroud)
我使用闭包吗?创建全局 [MyCystomDataType]。或者我如何实现这一目标?请注意异步任务,因为我显示的表格单元格有点像 facebook 或 instagram 新闻提要页面。
我知道这听起来不对!但是我需要实现的是在主线程上运行一个巨大的枚举,这显然会阻塞整个应用程序。我正在寻找的是某种动画或循环周期之间的延迟,以便其他代码可以执行。这是我的代码:
for (NSTextCheckingResult* match in matchedArray) {
dispatch_async(dispatch_get_main_queue(), ^{
[self addAttributes:@{NSBackgroundColorAttributeName:[UIColor redColor]} range:match.range];
});
}
Run Code Online (Sandbox Code Playgroud)
如注释中所述,此代码与UI相关,必须在主线程上运行。
我也尝试过,dispatch_after
但似乎它将在等待时间上阻塞线程。无论如何,我可以做到这一点,还是必须重做整个逻辑?
当我使用dispatch_after方法产生延迟时,它永远不会在它之后执行代码.我需要返回一个数组,但它总是跳过它.
这是matt的延迟方法:
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
Run Code Online (Sandbox Code Playgroud)
以下是发生错误的方法:
func rollDice() -> Array<Int> {
var diceArray = [Int]()
let timerTime:NSTimeInterval = 0.3
delay(timerTime) {
//my code
}
return diceArray //NEVER GETS HERE
}
Run Code Online (Sandbox Code Playgroud) 我有以下功能,假设[CIImage]
为了我的目的返回- 在tableView中显示照片的一些元数据.
func getCIImages() -> [CIImage] {
var images = [CIImage]()
let assets = PHAsset.fetchAssetsWithMediaType(.Image, options: nil)
for i in 0..<assets.count {
guard let asset = assets[i] as? PHAsset else {fatalError("Cannot cast as PHAsset")}
let semaphore = dispatch_semaphore_create(0)
asset.requestContentEditingInputWithOptions(nil) { contentEditingInput, _ in
//Get full image
guard let url = contentEditingInput?.fullSizeImageURL else {return}
guard let inputImage = CIImage(contentsOfURL: url) else {return}
images.append(inputImage)
dispatch_semaphore_signal(semaphore)
}
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
}
return images
}
Run Code Online (Sandbox Code Playgroud)
但它停留在信号量等待,并没有走得更远.我已经浏览了很多教程,但GCD的其他变种不起作用.我认为这是因为模拟器,我不知道,无法在真实设备上进行测试.请帮忙.
我正在使用dispatch_queue_t创建一个GCD队列q1 = dispatch_queue_create("com.s1",NULL);
并使用dispatch_async在其上调度块
GCD是否对运行的线程做出任何保证?我注意到它总是在后台线程上执行.是否有可能在主/ UI线程上执行它.GCD如何决定运行什么线程?
这是我的第一个Grand Central Dispatch代码,但它不起作用.使用Mac OS X 10.8和最新的Xcode版本.我知道这太基础了.谢谢.
#import <Foundation/Foundation.h>
#import <dispatch/dispatch.h>
void printResult(int r);
void printResult(int r)
{
NSLog(@"%i", r);
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
dispatch_async(queue, ^{
int number = pow(2, 5);
dispatch_async(dispatch_get_main_queue(), ^{
printResult(number);
});
});
}
return 0;
}
Run Code Online (Sandbox Code Playgroud) ios ×6
swift ×6
objective-c ×3
timer ×2
animation ×1
asynchronous ×1
cocoa ×1
concurrency ×1
iphone ×1
phasset ×1
semaphore ×1
swift4 ×1
xcode ×1