라이브러리에서 NSProgress
지원을 구현 중이며 모든 것이 제대로 작동하는지 테스트하기 위해 일부 단위 테스트를 작성했습니다. 이상적으로 나는 일부 추가 메타 데이터 (userInfo
키는 NSProgress
자체에서 사용하지 않지만 내 API 사용자는 사용할 수 있음)를 전달할 수 있기를 원하지만 현재는 localizedDescription
및 localizedAdditionalDescription
을 문서와 같이 작동 시키려고합니다. 그들은해야한다고 말한다. 테스트 할 방법은 아카이브에서 파일을 추출하므로 kind
을 NSProgressKindFile
으로 설정하고 파일 작업과 관련된 다양한 키 (예 : NSProgressFileCompletedCountKey
)를 설정합니다.자식 NSProgress 인스턴스의 NSProgress userInfo 변경 방법
처리 "테스트 파일 B.jpg"
처리 "a.txt이 테스트 파일"내가 KVO와
localizedDescription
에 변화를 관찰 할 때는 나는이 같은 업데이트를 볼 것으로 기대
처리 "테스트 파일 C.m4a"나는 중단 점 및
po
상기 정지
작업자의 localizedDescription
NSProgress
인스턴스 (childProgress
)가 실제로 표시됩니다. 내 테스트를 실행할 때, 그들은 모두 볼 다음이가 userInfo
키 중 하나가 표시되지 않는 것 의미이며, 내가 설정 :
0,123,516 완료0 %
0 % 완료
53 % 완료
를 완료% 100 %가
100
완료userInfo
키에 설정된 NSProgress
인스턴스의 키가 fractionCompleted
인데도 부모에게 전달되지 않는 것 같습니다. 내가 뭔가 잘못하고 있는거야?
아래에 추상 코드 조각을 몇 개 제공하지만 변경 사항이 적용된 커밋을 다운로드 할 수도 있습니다. from GitHub. 이 문제를 재현하려면 -[ProgressReportingTests testProgressReporting_ExtractFiles_Description]
및 -[ProgressReportingTests testProgressReporting_ExtractFiles_AdditionalDescription]
테스트 사례를 실행하십시오. 내 테스트 케이스 클래스에서
: 다음
static void *ProgressContext = &ProgressContext;
...
- (void)testProgressReporting {
NSProgress *parentProgress = [NSProgress progressWithTotalUnitCount:1];
[parentProgress becomeCurrentWithPendingUnitCount:1];
[parentProgress addObserver:self
forKeyPath:NSStringFromSelector(@selector(localizedDescription))
options:NSKeyValueObservingOptionInitial
context:ProgressContext];
MyAPIClass *apiObject = // initialize
[apiObject doLongRunningThing];
[parentProgress resignCurrent];
[parentProgress removeObserver:self
forKeyPath:NSStringFromSelector(@selector(localizedDescription))];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context
{
if (context == ProgressContext) {
// Should refer to parentProgress from above
NSProgress *notificationProgress = object;
[self.descriptionArray addObject:notificationProgress.localizedDescription];
}
}
, 내 수업 시간에 시험 :
- (void) doLongRunningThing {
...
NSProgress *childProgress = [NSProgress progressWithTotalUnitCount:/* bytes calculated above */];
progress.kind = NSProgressKindFile;
[childProgress setUserInfoObject:@0
forKey:NSProgressFileCompletedCountKey];
[childProgress setUserInfoObject:@(/*array count from above*/)
forKey:NSProgressFileTotalCountKey];
int counter = 0;
for /* Long-running loop */ {
[childProgress setUserInfoObject: // a file URL
forKey:NSProgressFileURLKey];
// Do stuff
[childProgress setUserInfoObject:@(++counter)
forKey:NSProgressFileCompletedCountKey];
childProgress.completedUnitCount += myIncrement;
}
}
내가 childProgress.completedUnitCount
을 증가시,이 사용자 정보는 디버거의 모습입니다.
> po childProgress.userInfo
{
NSProgressFileCompletedCountKey = 2,
NSProgressFileTotalCountKey = 3,
NSProgressFileURLKey = "file:///...Test%20File%20B.jpg"; // chunk elided from URL
}
각 KVO 알림이 돌아 오면
, 이것은notificationProgress.userInfo
보이는 방법은 다음과 같습니다 :
> po notificationProgress.userInfo
{
}
컨텍스트에 대해 더 많은 코드를 표시 할 수 있습니까? setUserInfoObject를 호출 한 직후 콘솔에 po myCustomObject, po MyCustomKey 및 po [childProgress userInfo]가 표시됩니다. – clarus
@clarus'po' 출력을 추가했습니다. 문맥에 필요한 다른 코드는 무엇입니까? 'NSProgress'와 관련이있는 것은별로 없습니다. 'fractionCompleted'가 정확하게보고되고 있습니다. – Dov
observeValueForKeyPath : ofObject의 코드는 무엇입니까? : change : context : look like? 그리고 위에서 parentProgress를 사용하는 곳은 원래 childProgress 객체 참조와 동일합니까? – clarus