我想使用dispatch_async偶爾從我的Web服務器中拉出一個正在更改的資源(大約每60秒)。dispatch_async不使用塊
我想使用dispatch_async,但我想給它一個函數名稱。因爲我想讓這個函數重新睡眠並重做相同的事情。
這就是我想要做dispatch_async(self.downloadQueue, @selector(getDataThread:));
(不編譯)
我認爲while循環是不是一個好主意,所以我想知道什麼是這個
我想使用dispatch_async偶爾從我的Web服務器中拉出一個正在更改的資源(大約每60秒)。dispatch_async不使用塊
我想使用dispatch_async,但我想給它一個函數名稱。因爲我想讓這個函數重新睡眠並重做相同的事情。
這就是我想要做dispatch_async(self.downloadQueue, @selector(getDataThread:));
(不編譯)
我認爲while循環是不是一個好主意,所以我想知道什麼是這個
如何最好的辦法關於類似...
NSTimer *timer = [NSTimer timerWithTimeInterval:60 target:self selector:@selector(getDataThread:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
- (void)getDataThread:(id)foo {
dispatch_async(self.downloadQueue, ^{
// code you want to run asynchronously
});
}
看來你想要的一些代碼塊異步運行...但你想,要還處於定時間隔運行,所以我覺得這應該足夠了。
如果你想溝塊和dispatch_async
乾脆你可以看看NSOperationQueue
,牢記NSOperationQueue
是建立在GCD但你並不需要擔心它直接接口。
一對夫婦的意見:
如果你想創建一個定時器被派遣操作,創建DISPATCH_SOURCE_TYPE_TIMER
類型的dispatch_source_t
,例如,定義了兩個類屬性:
@property (nonatomic, strong) dispatch_queue_t queue;
@property (nonatomic, strong) dispatch_source_t timer;
而且然後創建計時器:
- (void)createTimer
{
self.queue = dispatch_queue_create("com.stackoverflow.16782529", 0);
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue);
if (self.timer)
{
dispatch_source_set_timer(self.timer,
dispatch_walltime(NULL, 0),
60ull * NSEC_PER_SEC,
1ull * NSEC_PER_SEC);
dispatch_source_set_event_handler(self.timer, ^{
NSLog(@"doing something");
});
dispatch_resume(self.timer);
}
}
順便說一句,像所有重複計時器,它可能是很好的做法在你viewDidAppear
創建和您的viewDidDisappear
刪除:
- (void)viewDidAppear:(BOOL)animated
{
[self createTimer];
}
- (void)viewDidDisappear:(BOOL)animated
{
dispatch_source_cancel(self.timer);
}
如果你不想使用塊,使用_f
相當於任何GCD功能。所有帶塊的GCD函數都有一個帶有C函數的引用(後綴爲_f
)。例如,使用上面的例子中,非塊移交會是什麼樣子:
- (void)createTimer
{
self.queue = dispatch_queue_create("com.stackoverflow.16782529", 0);
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue);
if (self.timer)
{
dispatch_source_set_timer(self.timer,
dispatch_walltime(NULL, 0),
60ull * NSEC_PER_SEC,
1ull * NSEC_PER_SEC);
dispatch_source_set_event_handler_f(self.timer, &myTimerHandler);
dispatch_resume(self.timer);
}
}
void myTimerHandler(void *context)
{
NSLog(@"doing something");
}
如果你想用一個NSTimer
(使用Objective-C的方法,而不是C函數),你可能有這樣的屬性:
@property (nonatomic, strong) dispatch_queue_t queue;
@property (nonatomic, strong) NSTimer *timer;
然後創建計時器的看法出現時,當它消失刪除:
- (void)viewDidAppear:(BOOL)animated
{
self.queue = dispatch_queue_create("com.stackoverflow.16782529", 0);
self.timer = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES];
}
- (void)viewDidDisappear:(BOOL)animated
{
[self.timer invalidate];
}
- (void)handleTimer:(NSTimer *)timer
{
dispatch_async(self.queue, ^{
NSLog(@"doing something");
});
}
就個人而言,如果你經常檢查這個,那麼可能是一個拉式體系結構(你每隔60秒不斷拉取數據)可能沒有意義。您可以考慮打開服務器的套接字並讓服務器在有數據更新時通知您(請參閱此Ray Wenderlich example),或採用推送通知(有關本地通知和推送通知的notifications documents討論,但對於此應用程序,您我會看看推送通知)。顯然,這些都需要更多的服務器開發,但它在架構上更加優雅/高效。順便說一下,如果您要每隔60秒觸發一次網絡事件,如果您是異步啓動網絡活動(通過#3的NSTimer
方法,或者您的網絡請求本身運行異步),您可能還需要引入一些檢查,以確保先前的請求在啓動另一個請求之前已完成。這是不可能的,但你應該檢查一下。如果您使用dispatch_source_create
方法並使用同步網絡請求,則這不是問題(因爲定時器在前一個完成之前不會被重新觸發),但除此之外,您可能需要小心,以免最終結束用網絡請求備份你的隊列。
在Xcode 7.1.1中'dispatch_source_t'不能是'strong'或'retain'。你的代碼不會編譯。 –
@Cœur - 不,那是不正確的。如果您看到該錯誤,那可能是因爲您將編譯器標誌'-DOS_OBJECT_USE_OBJC = 0'設置爲'
我的項目中沒有OS_OBJECT_USE_OBJC標誌 –
如果你可以將它重構成C函數,你可以使用'dispatch_async_f()' – CodaFi