2013-05-28 84 views
1

我想使用dispatch_async偶爾從我的Web服務器中拉出一個正在更改的資源(大約每60秒)。dispatch_async不使用塊

我想使用dispatch_async,但我想給它一個函數名稱。因爲我想讓這個函數重新睡眠並重做相同的事情。

這就是我想要做dispatch_async(self.downloadQueue, @selector(getDataThread:));(不編譯)

我認爲while循環是不是一個好主意,所以我想知道什麼是這個

+2

如果你可以將它重構成C函數,你可以使用'dispatch_async_f()' – CodaFi

回答

0

如何最好的辦法關於類似...

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但你並不需要擔心它直接接口。

+0

真棒,我認爲這應該工作。只要應用程序處於打開狀態,我就希望發生這種情況。我可以把它放在didFinishLaunchingWithOptions中嗎? – jamesatha

+0

當然,我認爲這應該沒問題,儘管我將它包裝在一個方法中,並將它放在'applicationWillEnterForeground:'中,然後停止'applicationDidEnterBackground:'下的定時器。 –

+0

以及如何停止計時器? – jamesatha

4

一對夫婦的意見:

  1. 如果你想創建一個定時器被派遣操作,創建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); 
    } 
    
  2. 如果你不想使用塊,使用_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"); 
    } 
    
  3. 如果你想用一個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"); 
        }); 
    } 
    
  4. 就個人而言,如果你經常檢查這個,那麼可能是一個拉式體系結構(你每隔60秒不斷拉取數據)可能沒有意義。您可以考慮打開服務器的套接字並讓服務器在有數據更新時通知您(請參閱此Ray Wenderlich example),或採用推送通知(有關本地通知和推送通知的notifications documents討論,但對於此應用程序,您我會看看推送通知)。顯然,這些都需要更多的服務器開發,但它在架構上更加優雅/高效。順便說一下,如果您要每隔60秒觸發一次網絡事件,如果您是異步啓動網絡活動(通過#3的NSTimer方法,或者您的網絡請求本身運行異步),您可能還需要引入一些檢查,以確保先前的請求在啓動另一個請求之前已完成。這是不可能的,但你應該檢查一下。如果您使用dispatch_source_create方法並使用同步網絡請求,則這不是問題(因爲定時器在前一個完成之前不會被重新觸發),但除此之外,您可能需要小心,以免最終結束用網絡請求備份你的隊列。

+0

在Xcode 7.1.1中'dispatch_source_t'不能是'strong'或'retain'。你的代碼不會編譯。 –

+0

@Cœur - 不,那是不正確的。如果您看到該錯誤,那可能是因爲您將編譯器標誌'-DOS_OBJECT_USE_OBJC = 0'設置爲''中描述的關閉對GCD類型的對象行爲。但是我在Xcode 7.1.1(以及Xcode 7.2 beta 3)中對此進行了重新測試,並且'strong'可以正常工作(事實上也是需要的)。 – Rob

+0

我的項目中沒有OS_OBJECT_USE_OBJC標誌 –

相關問題