IOS crash with waitForExpectationsWithTimeout

Tests randomly fail using waitForExpectation , always if I execute a wait in dispatch_after .

This happens in both objective-c and swift.

Completely random, sometimes it sometimes works. Anyone have any ideas? (I run it with CMD + U on MacMini, but I also tried with MBP Retina, the same results)

Code example:

 func testBarcodeNotFound() { let exp = self.expectationWithDescription("store loading") OHHTTPStubs.stubRequestsPassingTest({ (request:NSURLRequest!) -> Bool in if request.URL.absoluteString == nil { return false } return request.URL.absoluteString!.hasSuffix("/products/barcode/1422/") }, withStubResponse: { (request:NSURLRequest!) -> OHHTTPStubsResponse! in let data = "".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true) return OHHTTPStubsResponse(data: data, statusCode: 404, headers: ["Content-Type":"application/json"]) }) self.productsVC.scanningVC.successScan("1422", "EAN13") dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in exp.fulfill() } self.waitForExpectationsWithTimeout(1, handler: nil) XCTAssertTrue(self.delegateForProductsVC.barcodeNotFoundCalled) } 

And backtrace

 (lldb) bt * thread #1: tid = 0x27e405, 0x06461ab0 libdispatch.dylib`_dispatch_semaphore_dispose + 92, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) frame #0: 0x06461ab0 libdispatch.dylib`_dispatch_semaphore_dispose + 92 frame #1: 0x06463578 libdispatch.dylib`_dispatch_dispose + 43 frame #2: 0x064759e1 libdispatch.dylib`_os_object_dispose + 33 frame #3: 0x06475cb1 libdispatch.dylib`-[OS_dispatch_object _xref_dispose] + 58 frame #4: 0x064759bb libdispatch.dylib`_os_object_xref_dispose + 33 frame #5: 0x05759eb1 libobjc.A.dylib`objc_release + 65 frame #6: 0x2011949d XCTest`__destroy_helper_block_95 + 29 frame #7: 0x064e4793 libsystem_sim_blocks.dylib`_Block_release + 211 frame #8: 0x0647603f libdispatch.dylib`_dispatch_client_callout + 14 frame #9: 0x0645f764 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 470 frame #10: 0x05af095e CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14 frame #11: 0x05aaf760 CoreFoundation`__CFRunLoopRun + 2256 frame #12: 0x05aaebcb CoreFoundation`CFRunLoopRunSpecific + 443 frame #13: 0x05aae9fb CoreFoundation`CFRunLoopRunInMode + 123 frame #14: 0x04c2ed98 Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 309 frame #15: 0x20119a31 XCTest`-[XCTestCase(AsynchronousTesting) waitForExpectationsWithTimeout:handler:] + 1192 * frame #16: 0x1055be0b SomeAppNative`SomeApp.ProductsDelegatesViewControllerTest.testBarcodeNotFound (self=0x7b0dbdf0)() -> () + 5595 at ProductsDelegatesViewControllerTest.swift:108 frame #17: 0x1055c1a2 SomeAppNative`@objc SomeApp.ProductsDelegatesViewControllerTest.testBarcodeNotFound (SomeApp.ProductsDelegatesViewControllerTest)() -> () + 34 at ProductsDelegatesViewControllerTest.swift:0 frame #18: 0x05a7976d CoreFoundation`__invoking___ + 29 frame #19: 0x05a79618 CoreFoundation`-[NSInvocation invoke] + 360 frame #20: 0x2010897b XCTest`-[XCTestCase invokeTest] + 320 frame #21: 0x20108bb9 XCTest`-[XCTestCase performTest:] + 184 frame #22: 0x20114162 XCTest`-[XCTest run] + 314 frame #23: 0x20107598 XCTest`-[XCTestSuite performTest:] + 406 frame #24: 0x20114162 XCTest`-[XCTest run] + 314 frame #25: 0x20107598 XCTest`-[XCTestSuite performTest:] + 406 frame #26: 0x20114162 XCTest`-[XCTest run] + 314 frame #27: 0x20107598 XCTest`-[XCTestSuite performTest:] + 406 frame #28: 0x20114162 XCTest`-[XCTest run] + 314 frame #29: 0x20103de2 XCTest`__25-[XCTestDriver _runSuite]_block_invoke + 61 frame #30: 0x20110c82 XCTest`-[XCTestObservationCenter _observeTestExecutionForBlock:] + 184 frame #31: 0x20103d06 XCTest`-[XCTestDriver _runSuite] + 285 frame #32: 0x20104951 XCTest`-[XCTestDriver _checkForTestManager] + 272 frame #33: 0x20104c6b XCTest`-[XCTestDriver runTestSuite:completionHandler:] + 378 frame #34: 0x2011775c XCTest`+[XCTestProbe runTests:] + 216 frame #35: 0x04c2ab57 Foundation`__NSFireDelayedPerform + 423 frame #36: 0x05af08d6 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22 frame #37: 0x05af025d CoreFoundation`__CFRunLoopDoTimer + 1309 frame #38: 0x05aaf6ba CoreFoundation`__CFRunLoopRun + 2090 frame #39: 0x05aaebcb CoreFoundation`CFRunLoopRunSpecific + 443 frame #40: 0x05aae9fb CoreFoundation`CFRunLoopRunInMode + 123 frame #41: 0x0712e24f GraphicsServices`GSEventRunModal + 192 frame #42: 0x0712e08c GraphicsServices`GSEventRun + 104 frame #43: 0x034518b6 UIKit`UIApplicationMain + 1526 frame #44: 0x0053dae5 SomeApp`main(argc=16, argv=0xbff6e4a4) + 213 at main.m:16 frame #45: 0x0649cac9 libdyld.dylib`start + 1 (lldb) 
+7
ios objective-c swift crash xctest
source share
3 answers

I had similar problems and it took me three days.

The documentation -waitForExpectationsWithTimeout:handler: says:

  * -waitForExpectationsWithTimeout:handler: runs the run loop while handling events until all expectations * are fulfilled or the timeout is reached. Clients should not manipulate the run * loop while using this API. 

Most likely, your NSInputStream or NSOutputStream trying to affect the runloop while waiting, which will result in a crash.

+1
source share

I had the same problem. The fix for me seemed to increase the timeout interval. Initially, I had a wait interval of 1 and increased to 5 to be safe. It seems to be working fine now. I'm not sure how long your asynchronous call will take, or if you can afford a longer timeout interval than 1, but it's worth it.

0
source share

Swift has particular problems to show the correct exception exception point when a close is present in the same area.

I saw the same problem in XCTestCase that used dispatch_after , and even through the exception checkpoint there was the same line as waitForExpectationsWithTimeout , the test case crashed due to downcast on the nil object.

I know that this is not your business, but whenever this happens, I suggest deleting statements one line at a time and running the test after each deletion. If the test does not fail, you have identified the culprit. This, unfortunately, is the best option at the time of this writing when Swift shows an exception checkpoint on a line that doesn't make sense, especially the infamous class 0 line, which you can see in crash reporting tools.

Let us know if you find out your accident.

0
source share

All Articles