2011-02-23 73 views
0

我正在嘗試創建一個線程,該線程配置運行循環以通過定義的NSTimer運行物理引擎。但是,我無法正常退出線程(或者我認爲問題是)。Objective-C線程:退出線程,保留問題

附上我的代碼的相關部分:

(該代碼是一個視圖控制器) (當按下一個按鈕背面被調用)

- (void)back { 

    [timestep invalidate]; 
    exiting = YES; 

    [self release]; 

} 

- (void)initializePhysicsWorld { 

    // Initializes the thread to simulate physics interactions. 
    [NSThread detachNewThreadSelector:@selector(physicsThreadMethod) 
          toTarget:self 
          withObject:nil]; 
} 

- (void)physicsThreadMethod { 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    NSRunLoop *myRunLoop = [NSRunLoop currentRunLoop]; 

    timestep = [NSTimer timerWithTimeInterval:1.0f/60.0f 
             target:self 
            selector:@selector(step:) 
            userInfo:nil 
             repeats:YES]; 

    [myRunLoop addTimer:timestep forMode:NSDefaultRunLoopMode]; 

    while (!exiting) { 

     CFRunLoopRun(); 

     [pool release]; 
     pool = [[NSAutoreleasePool alloc] init]; // periodically refreshes pool 
    } 
    CFRunLoopStop([myRunLoop getCFRunLoop]); 
    NSLog(@"Thread is going to exit"); 
    [pool release]; 

} 

- (void)dealloc { 
    if ([self.view superview]) { 
     [self.view removeFromSuperview]; 
    } 

    [super dealloc]; 
} 

發動機(以下步驟:函數)運行良好,但是當我嘗試通過運行該方法退出循環時,看起來該線程不會在我的視圖控制器上釋放其保留(dealloc未被調用)。我認爲我的線程沒有退出physicsThreadMethod方法,因爲NSLog沒有出現在控制檯中。當我第二次運行「返回」時,Dealloc才被調用。

我不確定爲什麼會發生這種情況,所以我非常感謝任何幫助。謝謝!

回答

0

問題就出在這裏:

while (!exiting) { 

    CFRunLoopRun(); //<-- here you start the run loop. 
    // the lines under this line are NEVER executed. also the while loop does nothing 
    [pool release]; 
    pool = [[NSAutoreleasePool alloc] init]; // periodically refreshes pool 
} 

你可以使用NSOperations來包裝你的工作,已經有這個類的定義做正是這種事情的性質。

如果你想堅持你的實現在NSThread你必須看看CFRunLoopreference以及如何添加觀察員到運行循環。

+0

謝謝!我將CFRunLoopRun()更改爲'[myRunLoop runUntilDate:]',現在它可以工作,除了基於放置在NSDate參數上的時間間隔有延遲。我想這不是最優雅的解決方案,但我現在要做的就是......我會讀到NSOperations。 :) – vemoxy 2011-02-23 08:59:58

+0

謝謝你的答案是有幫助的,將其標記爲正確的答案。 – GorillaPatch 2011-02-23 11:43:10

+0

順便說一句你的解決方案是相當黑客... – GorillaPatch 2011-02-23 11:43:39

0

CFRunLoopRun是否返回每一步:? CFRunLoopStop或[myRunLoop runUntilDate:]會有所幫助。

+0

是的,我意識到CFRunLoopRun不會返回。我已將它更改爲 '[myRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]' 但它似乎仍然不工作,只是while循環中的代碼現在運行。我認爲目前的問題是在線程退出之前調用'[self release]'。 – vemoxy 2011-02-23 08:46:31

+0

自我保留自NSThread和NSTimer。所以[自我釋放]只會影響自我的保留數。 – 2011-02-23 09:00:38

+0

「volatile BOOL退出」如何? – 2011-02-23 09:01:03