NSProgress::completedUnitCount 设置器挂起
Posted
技术标签:
【中文标题】NSProgress::completedUnitCount 设置器挂起【英文标题】:NSProgress::completedUnitCount setter hangs 【发布时间】:2016-01-04 11:27:41 【问题描述】:(void)URLSession:(NSURLSession *)session 任务:(NSURLSessionTask *)任务 didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend self.progress.completedUnitCount = totalBytesSent; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 这挂在 ios 9.0 有什么想法该怎么办???
(void)URLSession:(NSURLSession *)会话任务:(NSURLSessionTask *)任务 didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend;在主线程上调用并不重要
(lldb) bt
* 线程#1:tid = 0xd6e1, 0x00000001984a0c6c libsystem_kernel.dylibsemaphore_wait_trap + 8, queue = 'com.apple.main-thread', activity = 'send control actions', 1 messages, stop reason = signal SIGSTOP
* frame #0: 0x00000001984a0c6c libsystem_kernel.dylib
semaphore_wait_trap + 8
帧#1:0x000000019857a97c libsystem_platform.dylib_os_semaphore_wait + 24
frame #2: 0x00000001007bd428 libdispatch.dylib
_dispatch_barrier_sync_f_slow + 600
帧#3:0x00000001835af270 Foundation-[NSConcreteObservationBuffer _receiveBox:] + 248
frame #4: 0x00000001836180b0 Foundation
_NSKVO1AdaptorDeliver + 388
帧#5:0x0000000183617ea0 Foundation_NSKVO1AdaptorSlowDeliver + 264
frame #6: 0x0000000183523b84 Foundation
-[NSKeyValueObservance observeValueForKeyPath:ofObject:change:context:] + 424
帧#7:0x00000001834ffdd4 FoundationNSKeyValueNotifyObserver + 304
frame #8: 0x00000001834ff8fc Foundation
NSKeyValueDidChange + 404
帧#9:0x00000001834ea114 Foundation-[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 120
frame #10: 0x000000018258fab0 CoreFoundation
__53-[__NSArrayM enumerateObjectsWithOptions:usingBlock:]_block_invoke + 132
帧 #11: 0x000000018258f9a8 CoreFoundation-[__NSArrayM enumerateObjectsWithOptions:usingBlock:] + 308
frame #12: 0x00000001836cc158 Foundation
-[NSProgress _setValueForKeys:settingBlock:] + 600
第 13 帧:0x00000001836cc87c Foundation`-[NSProgress setCompletedUnitCount:] + 124
PS:如果我避免将 UIProgressView::observedProgress 设置为 NSProgress,它可以正常工作!?
【问题讨论】:
【参考方案1】:忙等待解决
-(void)showUploadingUI
myHardAssert([[NSThread currentThread] isMainThread], @"");
self.progressView.hidden = NO;
NSProgress *progress = urlsession.progress;
if( [self.progressView respondsToSelector:@selector(observedProgress)])
// this causes hang self.progressView.observedProgress = progress;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^
while(progress.completedUnitCount < progress.totalUnitCount)
dispatch_sync(dispatch_get_main_queue(), ^
self.progressView.progress = progress.fractionCompleted;
);
[NSThread sleepForTimeInterval:0.033];
dispatch_sync(dispatch_get_main_queue(), ^
self.progressView.progress = 1;
);
....
附带的好处是向后兼容 ios
【讨论】:
【参考方案2】:男孩这样做对我有帮助。递增 Progress.completedUnitCount
时,我的应用程序冻结了。 (在主线程上。)我假设这会触发一个设置器,因为有一个副作用——移动进度条,这是这样做的全部原因。
我的 Swift 4 解决方案是这样包装调用:
DispatchQueue.global(qos: .utility).async
self._decompressionProgress.completedUnitCount += 1
我仍然不太明白为什么会这样......很多事情都不同。
【讨论】:
以上是关于NSProgress::completedUnitCount 设置器挂起的主要内容,如果未能解决你的问题,请参考以下文章