주 코드 경로가 실행되는 방식에서 GUI 업데이트가 실행될 때까지 기다릴 필요가 없도록해야합니다. 게시 한 첫 번째 코드 블록에서 dispatch_sync
은 틀림없이 (dispatch_async
대) 거의 틀림없이 주 스레드에서 기다리는 백그라운드 스레드를 차단할 것이기 때문에()이 코드로 이어질 수 있습니다 (dispatch_sync
뒤에 코드가 없음). 스레드 기아 (배치 상태). 당신이 그것을 dispatch_sync
으로 만들었을 때 두 개의 병렬 작업을 연동하기 위해 대기열 자체를 사용하려고 시도한 것 같습니다. 당신이 정말 다소 차선의 방법을 사용하기 위해 최선을 다하고 있습니다 경우, 당신이 뭔가를 할 수 있습니다 : 가장 가까운 당신이 이미 가지고 무엇을 보였다 접근을했지만, 내가 할 수있는 뭔가를 내놓았다
- (void)testOne
{
SOAltUpdateView* view = [[SOAltUpdateView alloc] initWithFrame: NSMakeRect(0, 0, 100, 100)];
STAssertNotNil(view, @"View was nil");
STAssertEqualObjects(view.color, [NSColor redColor] , @"Initial color was wrong");
dispatch_queue_t q = dispatch_queue_create("test", 0);
dispatch_group_t group = dispatch_group_create();
view.queue = q;
// Run the operation
[view update];
// An operation we can wait on
dispatch_group_async(group, q, ^{ });
while (dispatch_group_wait(group, DISPATCH_TIME_NOW))
{
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, YES);
}
STAssertEqualObjects(view.color, [NSColor greenColor] , @"Updated color was wrong");
view.queue = nil;
[view release];
dispatch_release(group);
dispatch_release(q);
}
좀 더 나은/청소기 : 세마포어 당신을 위해이 연동을 할 수 있고 약간의 노력으로, 당신은 실제 GUI 코드에 대한 침입을 최소화 할 수 있습니다. (참고 :
에 침입을 사용하는 것은 사실상 불가능합니다. 두 개의 병렬 작업을 인터 로킹하려면
에 의 코드를 공유해야합니다. - 기존 코드에서 뭔가 공유되었습니다. 대기열, 여기서 세마포어를 사용하고 있습니다.)이 고안된 예제를 고려해보십시오. 백그라운드 작업이 완료 될 때이를 알리는 데 사용할 수있는 세마포어를 테스트 하네스에 전달하는 일반적인 방법을 추가했습니다. 테스트 할 코드의 "침입"은 두 개의 매크로로 제한됩니다.
NSObject의 + AsyncGUITestSupport.h :
@interface NSObject (AsyncGUITestSupport)
@property (nonatomic, readwrite, assign) dispatch_semaphore_t testCompletionSemaphore;
@end
#define OPERATION_BEGIN(...) do { dispatch_semaphore_t s = self.testCompletionSemaphore; if (s) dispatch_semaphore_wait(s, DISPATCH_TIME_NOW); } while(0)
#define OPERATION_END(...) do { dispatch_semaphore_t s = self.testCompletionSemaphore; if (s) dispatch_semaphore_signal(s); } while(0)
NSObject의 + AsyncGUITestSupport.m :
#import "NSObject+AsyncGUITestSupport.h"
#import <objc/runtime.h>
@implementation NSObject (AsyncGUITestSupport)
static void * const kTestingSemaphoreAssociatedStorageKey = (void*)&kTestingSemaphoreAssociatedStorageKey;
- (void)setTestCompletionSemaphore:(dispatch_semaphore_t)myProperty
{
objc_setAssociatedObject(self, kTestingSemaphoreAssociatedStorageKey, myProperty, OBJC_ASSOCIATION_ASSIGN);
}
- (dispatch_semaphore_t)testCompletionSemaphore
{
return objc_getAssociatedObject(self, kTestingSemaphoreAssociatedStorageKey);
}
@end
SOUpdateView.h
@interface SOUpdateView : NSView
@property (nonatomic, readonly, retain) NSColor* color;
- (void)update;
@end
SOUpdateView.m
#import "SOUpdateView.h"
#import "NSObject+AsyncGUITestSupport.h"
@implementation SOUpdateView
{
NSUInteger _count;
}
- (NSColor *)color
{
NSArray* colors = @[ [NSColor redColor], [NSColor greenColor], [NSColor blueColor] ];
@synchronized(self)
{
return colors[_count % colors.count];
}
}
- (void)drawRect:(NSRect)dirtyRect
{
[self.color set];
NSRectFill(dirtyRect);
}
- (void)update
{
OPERATION_BEGIN();
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
@synchronized(self)
{
_count++;
}
dispatch_async(dispatch_get_main_queue(), ^{
[self setNeedsDisplay: YES];
OPERATION_END();
});
});
}
@end
그리고 테스트 환경 :이 도움이
#import "TestSOTestGUI.h"
#import "SOUpdateView.h"
#import "NSObject+AsyncGUITestSupport.h"
@implementation TestSOTestGUI
- (void)testOne
{
SOUpdateView* view = [[SOUpdateView alloc] initWithFrame: NSMakeRect(0, 0, 100, 100)];
STAssertNotNil(view, @"View was nil");
STAssertEqualObjects(view.color, [NSColor redColor] , @"Initial color was wrong");
// Push in a semaphore...
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
view.testCompletionSemaphore = sem;
// Run the operation
[view update];
// Wait for the operation to finish.
while (dispatch_semaphore_wait(sem, DISPATCH_TIME_NOW))
{
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, YES);
}
// Clear out the semaphore
view.testCompletionSemaphore = nil;
STAssertEqualObjects(view.color, [NSColor greenColor] , @"Updated color was wrong");
}
@end
희망.
다른 스레드 또는 큐에서 단위 테스트를 실행할 수 없습니까? –