My app functions correctly, but when I enable an "all exception" breakpoint it fails during this segue (gotoHome). If I bypass the navigation controller and go directly to the initial viewcontroller for the navigation controller the segue works fine with the breakpoint enabled.
I am not subclassing or overriding the UINavigationController. But like I said if I disable the exception breakpoint it works just fine, but I need to be able to enable this to be able to better debug other parts of the application.
Any help would be great.
viewDidAppear from initial StartupViewController. I have tried with and without the timer with same issue.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { t in
let u = XXXXXgetUsername()
let p = XXXXXgetPassword()
if (u == "" || p == "") {
self.performSegue(withIdentifier: "gotoLogin", sender: self)
} else {
if (getPIN() != "" && !pinVerified) {
self.performSegue(withIdentifier: "gotoPIN", sender: self)
} else {
//FAILS at this segue
self.performSegue(withIdentifier: "gotoHome", sender: self) //LINE 37
}
}
}
}
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000103ff8f11 libobjc.A.dylib`objc_exception_throw
frame #1: 0x0000000105702079 CoreFoundation`-[NSException raise] + 9
frame #2: 0x0000000103a17a63 Foundation`-[NSObject(NSKeyValueCoding)
setValue:forKey:] + 292
frame #3: 0x0000000106745117 UIKit`-[UIViewController setValue:forKey:] + 87
frame #4: 0x0000000106f6bea3 UIKit`-[UINibKeyValuePair apply] + 63
frame #5: 0x00000001056a53cd CoreFoundation`-[NSArray
makeObjectsPerformSelector:] + 317
frame #6: 0x0000000106a355d0 UIKit`-[UINib instantiateWithOwner:options:] +
1837
frame #7: 0x0000000106ec5fc2 UIKit`-[UIStoryboard
instantiateViewControllerWithIdentifier:] + 181
frame #8: 0x0000000106ed5874 UIKit`-[UIStoryboardSegueTemplate
instantiateOrFindDestinationViewControllerWithSender:] + 90
frame #9: 0x0000000106ed5ab8 UIKit`-[UIStoryboardSegueTemplate _perform:] + 52
frame #10: 0x0000000106750324 UIKit`-[UIViewController
performSegueWithIdentifier:sender:] + 99
* frame #11: 0x0000000102356516 XXXXXIOS`closure #1 in
StartupViewController.viewDidAppear(t=0x0000608000167ec0,
self=0x00007ffd4ed061d0) at StartupViewController.swift:37
frame #12: 0x00000001023565ea XXXXXIOS`partial apply for closure #1 in
StartupViewController.viewDidAppear(_:) at StartupViewController.swift:0
frame #13: 0x000000010222fcee XXXXXIOS`thunk for #callee_owned (#owned Timer)
-> () at SensorViewController.swift:0
frame #14: 0x0000000103a60b1e Foundation`__NSFireTimer + 83
frame #15: 0x0000000105692174
CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
frame #16: 0x0000000105691e32 CoreFoundation`__CFRunLoopDoTimer + 1026
frame #17: 0x00000001056919ea CoreFoundation`__CFRunLoopDoTimers + 266
frame #18: 0x0000000105689404 CoreFoundation`__CFRunLoopRun + 2308
frame #19: 0x0000000105688889 CoreFoundation`CFRunLoopRunSpecific + 409
frame #20: 0x000000010d3929c6 GraphicsServices`GSEventRunModal + 62
frame #21: 0x00000001065a55d6 UIKit`UIApplicationMain + 159
frame #22: 0x000000010243a2a7 XXXXXIOS`main at AppDelegate.swift:13
frame #23: 0x00000001093d6d81 libdyld.dylib`start + 1
I deleted the view in the storyboard a recreated and linked my view controller to the new view and the exception went away. Not sure what the error was but this solved it.
Related
I'm creating UISwitch that controls two view controllers, and I need to share data of UISwitch condition between them. I tried to use User Defaults but got SIGABRT error. What do I need to fix to get it working?
// Its view with UISwitch
#IBAction func SwitchThemeColor(_ sender: UISwitch) {
if SwitchTheme.isOn || traitCollection.userInterfaceStyle == .dark {
view.backgroundColor = UIColor.black
UserDefaults.standard.set(true, forKey: "switchState")
UserDefaults.standard.synchronize()
}
// And that is the view where I want to transfer UISwitch condition
if UserDefaults.standard.bool(forKey: "switchState") == true {
view.backgroundColor = UIColor.black
}
expected: that data transfers and switch controls background of two views
actual: SIGABRT error and it did not work
also I write bt in output and get this:
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x00007fff513782c6 libsystem_kernel.dylib`__pthread_kill + 10
frame #1: 0x00007fff5141fbf1 libsystem_pthread.dylib`pthread_kill + 284
frame #2: 0x00007fff51308a5c libsystem_c.dylib`abort + 120
frame #3: 0x00007fff4f22e7f8 libc++abi.dylib`abort_message + 231
frame #4: 0x00007fff4f22e9c7 libc++abi.dylib`demangling_terminate_handler() + 262
frame #5: 0x00007fff503b5d7c libobjc.A.dylib`_objc_terminate() + 96
frame #6: 0x00007fff4f23be97 libc++abi.dylib`std::__terminate(void (*)()) + 8
frame #7: 0x00007fff4f23be39 libc++abi.dylib`std::terminate() + 41
frame #8: 0x00007fff503b5d1c libobjc.A.dylib`objc_terminate + 9
frame #9: 0x000000010ff1cd78 libdispatch.dylib`_dispatch_client_callout + 28
frame #10: 0x000000010ff1fcd5 libdispatch.dylib`_dispatch_block_invoke_direct + 300
frame #11: 0x00007fff3633108a FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 30
frame #12: 0x00007fff36330d78 FrontBoardServices`-[FBSSerialQueue _queue_performNextIfPossible] + 441
frame #13: 0x00007fff36331287 FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 22
frame #14: 0x00007fff23afbac1 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
frame #15: 0x00007fff23afb9ec CoreFoundation`__CFRunLoopDoSource0 + 76
frame #16: 0x00007fff23afb21c CoreFoundation`__CFRunLoopDoSources0 + 268
frame #17: 0x00007fff23af5ecf CoreFoundation`__CFRunLoopRun + 1263
frame #18: 0x00007fff23af56b6 CoreFoundation`CFRunLoopRunSpecific + 438
frame #19: 0x00007fff3815cbb0 GraphicsServices`GSEventRunModal + 65
frame #20: 0x00007fff47162a67 UIKitCore`UIApplicationMain + 1621
* frame #21: 0x000000010fa7bdab TabbedAppTest`main at AppDelegate.swift:12:7
frame #22: 0x00007fff5123bcf5 libdyld.dylib`start + 1
frame #23: 0x00007fff5123bcf5 libdyld.dylib`start + 1
Problem is somewhere else - this code should works.
You mention in comment, that you get error message: Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<TabbedAppTest.SecondViewController 0x7f8d84516c60> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key BarItem.
It looks like you have in storyboard/xib file some old outlet for key BarItem in you SecondViewController class. Probably you removed outlet from code programmatically, but outlet in storyboard/xib stays.
When I try to save a new object into core data I am getting this error and a crash when I try to save the context:
libc++abi.dylib: terminating with uncaught exception of type NSException
I have used the same method to save a newly created managed object in a number of other view controllers and all work fine except in this one. The issue started when I changed this line:
var managedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
from .mainQueueConcurrencyType in the AppDelegate.
This is my persistent store coordinator setup in AppDel:
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return coordinator
}()
and this is the series of functions that lead up to the crash:
//get a new model for the components, same context, new FRC
purchaseOrderModel = StockModel()
purchaseOrderModel.setupManagedObjectContext()
purchaseOrderModel.tableView = tableView
if purchaseOrder == nil {
//delegate?.editModeStateChange(editing: true)
purchaseOrder = purchaseOrderModel.savePurchaseOrderWith("", supplier: nil, issueDate: Date(), deliveryDate: Date(), deliveryStatus: false)
delegate?.newItemAdded()
creatingNewPurchaseOrder = true
}
calls to
func savePurchaseOrderWith(_ poId: String?, supplier: NSManagedObject?, issueDate: Date, deliveryDate: Date, deliveryStatus: Bool? = nil) -> NSManagedObject {
let newPurchaseOrder = NSEntityDescription.insertNewObject(forEntityName: "Purchase_Order", into: context)
newPurchaseOrder.setValue(poId, forKey: "po_id")
newPurchaseOrder.setValue(issueDate, forKey: "issue_date")
newPurchaseOrder.setValue(deliveryDate, forKey: "est_delivery_date")
newPurchaseOrder.setValue(supplier, forKey: "supplier")
newPurchaseOrder.setValue(deliveryStatus, forKey: "delivered")
_ = doSaveContext()
return newPurchaseOrder
}
doSaveContext:
func doSaveContext() -> Bool {
do {
try context.save() //editing POs makes it crash here after changing the created context in app delegate
return true
} catch let error as NSError {
print("Error saving context after delete \(error.localizedDescription)")
return false
}
}
and I get a SIGBART on try context.save()
It's been a couple of months since I worked on this project but this is what ground development to a halt so help would be great. What is weird is that every other path that creates a new empty object (say a delivery, new product etc) that ends in doSaveContext() works fine.
Happy to post extra information etc.
Update 1: When adding an exception break point it breaks in this function of my model class:
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type{
case NSFetchedResultsChangeType.insert:
//note that for insert we insert a row at _newIndexPath_
if let insertIndexPath = newIndexPath {
self.tableView.insertRows(at: [insertIndexPath], with: UITableViewRowAnimation.fade)
}
case NSFetchedResultsChangeType.delete:
//note that for delete we delete the row at _indexPath_
if let deleteIndexPath = indexPath {
self.tableView.deleteRows(at: [deleteIndexPath], with: UITableViewRowAnimation.fade)
}
case NSFetchedResultsChangeType.update:
//note that for update we update the row at _indexPath_
if indexPath != nil {
// let cell = self.tableView.cellForRowAtIndexPath(updateIndexPath)
// let supplier = fetchedResultsController.objectAtIndexPath(updateIndexPath)
// cell!.textLabel?.text = supplier.name
}
case NSFetchedResultsChangeType.move:
//note that for Move we delete the row at _indexPath_
if let deleteIndexPath = indexPath {
self.tableView.insertRows(at: [deleteIndexPath], with: UITableViewRowAnimation.fade)
}
//note that for move we insert a row at _newIndexPath_
if let insertIndexPath = newIndexPath {
self.tableView.insertRows(at: [insertIndexPath], with: UITableViewRowAnimation.fade)
}
}
}
on the self.tableView.insertRows(at: [insertIndexPath], with: UITableViewRowAnimation.fade) line if that helps. Can't find a clear log anywhere.
Update 2: Typing bt in the console when it breaks produces this:
(lldb) bt
* thread #1, queue = 'NSManagedObjectContext 0x6040003cb8b0', stop reason = breakpoint 1.2
frame #0: 0x000000010c8e3b86 libc++abi.dylib`__cxa_throw
frame #1: 0x0000000106ee2068 libobjc.A.dylib`objc_exception_throw + 343
frame #2: 0x0000000107ff8362 CoreFoundation`+[NSException raise:format:arguments:] + 98
frame #3: 0x0000000106986089 Foundation`-[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
frame #4: 0x00000001096d9430 UIKit`-[UITableView _endCellAnimationsWithContext:] + 18124
frame #5: 0x00000001096f5524 UIKit`-[UITableView _updateRowsAtIndexPaths:withUpdateAction:rowAnimation:usingPresentationValues:] + 1342
frame #6: 0x00000001096f55f7 UIKit`-[UITableView insertRowsAtIndexPaths:withRowAnimation:] + 118
* frame #7: 0x00000001062013fd SC Dev`StockModel.controller(controller=0x00006000000efe00, anObject=Any # 0x00007fff59ae7458, indexPath=nil, type=insert, newIndexPath=2 indices, self=0x0000600000478940) at StockModel.swift:283
frame #8: 0x0000000106201f30 SC Dev`#objc StockModel.controller(_:didChange:at:for:newIndexPath:) at StockModel.swift:0
frame #9: 0x0000000107b6ef17 CoreData`__82-[NSFetchedResultsController(PrivateMethods) _core_managedObjectContextDidChange:]_block_invoke + 5767
frame #10: 0x0000000107a13bf8 CoreData`developerSubmittedBlockToNSManagedObjectContextPerform + 168
frame #11: 0x000000010cccb43c libdispatch.dylib`_dispatch_client_callout + 8
frame #12: 0x000000010ccd2338 libdispatch.dylib`_dispatch_queue_barrier_sync_invoke_and_complete + 392
frame #13: 0x0000000107a13afe CoreData`-[NSManagedObjectContext performBlockAndWait:] + 286
frame #14: 0x0000000107b6d877 CoreData`-[NSFetchedResultsController(PrivateMethods) _core_managedObjectContextDidChange:] + 119
frame #15: 0x0000000107f8f07c CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
frame #16: 0x0000000107f8ef7a CoreFoundation`_CFXRegistrationPost + 442
frame #17: 0x0000000107f8ecc2 CoreFoundation`___CFXNotificationPost_block_invoke + 50
frame #18: 0x0000000107f50a32 CoreFoundation`-[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1826
frame #19: 0x0000000107f4fbac CoreFoundation`_CFXNotificationPost + 652
frame #20: 0x00000001068c3842 Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 66
frame #21: 0x00000001079fcbd5 CoreData`-[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 773
frame #22: 0x0000000107a9e0ca CoreData`-[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:deletions:updates:refreshes:deferrals:wasMerge:] + 1658
frame #23: 0x00000001079f6f0f CoreData`-[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 2399
frame #24: 0x00000001079fa7d3 CoreData`-[NSManagedObjectContext save:] + 419
frame #25: 0x00000001062032fc SC Dev`StockModel.doSaveContext(self=0x0000600000673000) at StockModel.swift:381
frame #26: 0x000000010620affd SC Dev`StockModel.savePurchaseOrderWith(poId="", supplier=nil, issueDate=2018-02-06 21:17:37 UTC, deliveryDate=2018-02-06 21:17:37 UTC, deliveryStatus=false, self=0x0000600000673000) at StockModel.swift:592
frame #27: 0x000000010626ce76 SC Dev`PurchaseOrderDetailViewController.viewDidLoad(self=0x00007f941e038800) at PurchaseOrderDetailViewController.swift:68
frame #28: 0x0000000106270f84 SC Dev`#objc PurchaseOrderDetailViewController.viewDidLoad() at PurchaseOrderDetailViewController.swift:0
frame #29: 0x000000010975ad51 UIKit`-[UIViewController loadViewIfRequired] + 1235
frame #30: 0x00000001097a24dc UIKit`-[UINavigationController _updateScrollViewFromViewController:toViewController:] + 68
frame #31: 0x00000001097a2818 UIKit`-[UINavigationController _startTransition:fromViewController:toViewController:] + 153
frame #32: 0x00000001097a392f UIKit`-[UINavigationController _startDeferredTransitionIfNeeded:] + 841
frame #33: 0x00000001097a4b90 UIKit`-[UINavigationController __viewWillLayoutSubviews] + 115
frame #34: 0x00000001099fb2ae UIKit`-[UILayoutContainerView layoutSubviews] + 231
frame #35: 0x000000010968b551 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1331
frame #36: 0x00000001093fb4ba QuartzCore`-[CALayer layoutSublayers] + 153
frame #37: 0x00000001093ff5a9 QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 401
frame #38: 0x00000001093881cd QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 365
frame #39: 0x00000001093b3ae4 QuartzCore`CA::Transaction::commit() + 500
frame #40: 0x00000001095e7687 UIKit`_afterCACommitHandler + 272
frame #41: 0x0000000107f95db7 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
frame #42: 0x0000000107f95d0e CoreFoundation`__CFRunLoopDoObservers + 430
frame #43: 0x0000000107f7a324 CoreFoundation`__CFRunLoopRun + 1572
frame #44: 0x0000000107f79a89 CoreFoundation`CFRunLoopRunSpecific + 409
frame #45: 0x000000010f6de9c6 GraphicsServices`GSEventRunModal + 62
frame #46: 0x00000001095bcd30 UIKit`UIApplicationMain + 159
frame #47: 0x0000000106142607 SC Dev`main at AppDelegate.swift:18
frame #48: 0x000000010cd47d81 libdyld.dylib`start + 1
Update 3: wrapping the _ = doSaveContext() in DispatchQueue.main.async { gets me a few steps further along but still breaks on the same table insert line as before with the below log.
bt
* thread #1, queue = 'NSManagedObjectContext 0x6000001da400', stop reason = breakpoint 1.1
frame #0: 0x000000010945bf11 libobjc.A.dylib`objc_exception_throw
frame #1: 0x000000010a572362 CoreFoundation`+[NSException raise:format:arguments:] + 98
frame #2: 0x0000000108f00089 Foundation`-[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
frame #3: 0x000000010b9e0430 UIKit`-[UITableView _endCellAnimationsWithContext:] + 18124
frame #4: 0x000000010b9fc524 UIKit`-[UITableView _updateRowsAtIndexPaths:withUpdateAction:rowAnimation:usingPresentationValues:] + 1342
frame #5: 0x000000010b9fc5f7 UIKit`-[UITableView insertRowsAtIndexPaths:withRowAnimation:] + 118
* frame #6: 0x000000010877a0cd SC Dev`StockModel.controller(controller=0x00006000000fea00, anObject=Any # 0x00007fff575731c8, indexPath=nil, type=insert, newIndexPath=2 indices, self=0x000060400046aa00) at StockModel.swift:283
frame #7: 0x000000010877ac00 SC Dev`#objc StockModel.controller(_:didChange:at:for:newIndexPath:) at StockModel.swift:0
frame #8: 0x000000010a0e8f17 CoreData`__82-[NSFetchedResultsController(PrivateMethods) _core_managedObjectContextDidChange:]_block_invoke + 5767
frame #9: 0x0000000109f8dbf8 CoreData`developerSubmittedBlockToNSManagedObjectContextPerform + 168
frame #10: 0x000000010f23843c libdispatch.dylib`_dispatch_client_callout + 8
frame #11: 0x000000010f23f338 libdispatch.dylib`_dispatch_queue_barrier_sync_invoke_and_complete + 392
frame #12: 0x0000000109f8dafe CoreData`-[NSManagedObjectContext performBlockAndWait:] + 286
frame #13: 0x000000010a0e7877 CoreData`-[NSFetchedResultsController(PrivateMethods) _core_managedObjectContextDidChange:] + 119
frame #14: 0x000000010a50907c CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
frame #15: 0x000000010a508f7a CoreFoundation`_CFXRegistrationPost + 442
frame #16: 0x000000010a508cc2 CoreFoundation`___CFXNotificationPost_block_invoke + 50
frame #17: 0x000000010a4caa32 CoreFoundation`-[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1826
frame #18: 0x000000010a4c9bac CoreFoundation`_CFXNotificationPost + 652
frame #19: 0x0000000108e3d842 Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 66
frame #20: 0x0000000109f76bd5 CoreData`-[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 773
frame #21: 0x000000010a0180ca CoreData`-[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:deletions:updates:refreshes:deferrals:wasMerge:] + 1658
frame #22: 0x0000000109f70f0f CoreData`-[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 2399
frame #23: 0x0000000109f747d3 CoreData`-[NSManagedObjectContext save:] + 419
frame #24: 0x000000010877bfcc SC Dev`StockModel.doSaveContext(self=0x000060000046fec0) at StockModel.swift:381
frame #25: 0x0000000108783ebe SC Dev`closure #1 in StockModel.savePurchaseOrderWith(self=0x000060000046fec0) at StockModel.swift:593
frame #26: 0x0000000108783f52 SC Dev`partial apply for closure #1 in StockModel.savePurchaseOrderWith(_:supplier:issueDate:deliveryDate:deliveryStatus:) at StockModel.swift:0
frame #27: 0x00000001086c0b89 SC Dev`thunk for #callee_owned () -> () at AddProductViewController.swift:0
frame #28: 0x000000010f2373f7 libdispatch.dylib`_dispatch_call_block_and_release + 12
frame #29: 0x000000010f23843c libdispatch.dylib`_dispatch_client_callout + 8
frame #30: 0x000000010f2436f0 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 628
frame #31: 0x000000010a52fef9 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
frame #32: 0x000000010a4f4662 CoreFoundation`__CFRunLoopRun + 2402
frame #33: 0x000000010a4f3a89 CoreFoundation`CFRunLoopRunSpecific + 409
frame #34: 0x0000000111c579c6 GraphicsServices`GSEventRunModal + 62
frame #35: 0x000000010b8c3d30 UIKit`UIApplicationMain + 159
frame #36: 0x00000001086bb2d7 SC Dev`main at AppDelegate.swift:18
frame #37: 0x000000010f2b4d81 libdyld.dylib`start + 1
(lldb)
It's impossible to be certain but your stack traces strongly suggest that the problem is related to updating your table view from NSFetchedResultsControllerDelegate callbacks. From one of your comments, the likeliest cause is that you're not calling beginUpdates() on the table view anywhere.
There are two basic approaches to updating a table view from NSFetchedResultsControllerDelegate. First, simple but not optimal: Don't implement controllerWillChangeContent(_:) or controller(_:didChange:at:for:newIndexPath:). Do implement controllerDidChangeContent(_:), but use that method to reloadData() on your table view. Don't bother with begin/end updates or inserting/deleting/etc rows.
The second, better but slightly more complex, is to do all of these:
Implement controllerWillChangeContent(_:) and use it to call beginUpdates().
Implement controller(_:didChange:at:for:newIndexPath:) to insert/update/etc rows in the table.
Implement controllerDidChangeContent(_:) and use it to call endUpdates().
The "begin" and "end" calls are both crucial. I can't be 100% sure that this is what's causing your specific crash, but I'd expect leaving out beginUpdates() to cause some kind of crash.
I have a button on ViewControllerA (Parent) that I want to update a variable inside of ViewControllerB (Child). ViewControllerB is a container view inside of ViewControllerA.
This is the variable in ViewControllerB I want to update multiple times from the Parent ViewControllerA button press:
#IBOutlet weak var childViewHeight: NSLayoutConstraint!
Because the child view, ViewControllerB, is connected by an embed segue, it seems I can only pass data from ViewControllerA to ViewControllerB once via the prepareForSegue method. The performSegue method causes the program to crash with a SIGABRT Error.
I know it is generally considered bad practice to try to update an IBOutlet from a separate class or view controller, but I need a way for a button press on ViewControllerA to change the height constraint for ViewControllerA and ViewControllerB simultaneously.
If this is impossible in my current approach, please give me another suggestion of how to redesign my app to make this possible.
Update - This is the code that causes the crash:
#IBAction func button(_ sender: AnyObject) {
performSegue(withIdentifier: "seg", sender: self)
}
Update - Here is the result when I type in "bt" in the debug console:
* thread #1: tid = 0x1fcdd, 0x000000010d9b1f06 libsystem_kernel.dylib`__pthread_kill + 10, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x000000010d9b1f06 libsystem_kernel.dylib`__pthread_kill + 10
frame #1: 0x000000010dad24ec libsystem_pthread.dylib`pthread_kill + 90
frame #2: 0x000000010d7040b3 libsystem_c.dylib`abort + 129
frame #3: 0x000000010d9d043a libc++abi.dylib`abort_message + 266
frame #4: 0x000000010d9f4a9f libc++abi.dylib`default_terminate_handler() + 267
frame #5: 0x000000010c7b559f libobjc.A.dylib`_objc_terminate() + 103
frame #6: 0x000000010d9f1c09 libc++abi.dylib`std::__terminate(void (*)()) + 8
frame #7: 0x000000010d9f1894 libc++abi.dylib`__cxa_rethrow + 99
frame #8: 0x000000010c7b54b7 libobjc.A.dylib`objc_exception_rethrow + 40
frame #9: 0x000000010a2eebf1 CoreFoundation`CFRunLoopRunSpecific + 433
frame #10: 0x000000010f6d7a48 GraphicsServices`GSEventRunModal + 161
frame #11: 0x000000010ad27e8b UIKit`UIApplicationMain + 159
* frame #12: 0x000000010a1c60cf ContainerVC2`main + 111 at AppDelegate.swift:12
frame #13: 0x000000010d6586bd libdyld.dylib`start + 1
Update - Here is the "bt" console output with the exception breakpoint in place:
* thread #1: tid = 0x219bd, 0x000000010afca2ee libobjc.A.dylib`objc_exception_throw, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x000000010afca2ee libobjc.A.dylib`objc_exception_throw
frame #1: 0x0000000108b7dec2 CoreFoundation`+[NSException raise:format:arguments:] + 98
frame #2: 0x0000000109079455 Foundation`-[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
frame #3: 0x0000000109f65309 UIKit`__67-[UIStoryboardEmbedSegueTemplate newDefaultPerformHandlerForSegue:]_block_invoke + 438
frame #4: 0x0000000109ce05e4 UIKit`-[UIStoryboardSegueTemplate _performWithDestinationViewController:sender:] + 453
frame #5: 0x0000000109ce03ee UIKit`-[UIStoryboardSegueTemplate _perform:] + 82
frame #6: 0x00000001096dc45b UIKit`-[UIViewController performSegueWithIdentifier:sender:] + 99
* frame #7: 0x00000001089d99b3 ContainerVC2`ViewController1.button(sender=0x00007fff57224658, self=0x00007fcddb707cb0) -> () + 131 at ViewController.swift:9
frame #8: 0x00000001089d9a26 ContainerVC2`#objc ViewController1.button(AnyObject) -> () + 54 at ViewController.swift:0
frame #9: 0x000000010953eb6f UIKit`-[UIApplication sendAction:to:from:forEvent:] + 83
frame #10: 0x00000001096bf927 UIKit`-[UIControl sendAction:to:forEvent:] + 67
frame #11: 0x00000001096bfc08 UIKit`-[UIControl _sendActionsForEvents:withEvent:] + 388
frame #12: 0x00000001096be6aa UIKit`-[UIControl touchesBegan:withEvent:] + 414
frame #13: 0x00000001095aabbd UIKit`-[UIWindow _sendTouchesForEvent:] + 1188
frame #14: 0x00000001095ac8d6 UIKit`-[UIWindow sendEvent:] + 3984
frame #15: 0x000000010955a1e1 UIKit`-[UIApplication sendEvent:] + 281
frame #16: 0x0000000109d1502f UIKit`__dispatchPreprocessedEventFromEventQueue + 3314
frame #17: 0x0000000109d0dc4e UIKit`__handleEventQueue + 4879
frame #18: 0x0000000108b1fcb1 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
frame #19: 0x0000000108b04c6c CoreFoundation`__CFRunLoopDoSources0 + 556
frame #20: 0x0000000108b04156 CoreFoundation`__CFRunLoopRun + 918
frame #21: 0x0000000108b03b5d CoreFoundation`CFRunLoopRunSpecific + 285
frame #22: 0x000000010deeca48 GraphicsServices`GSEventRunModal + 161
frame #23: 0x000000010953ce8b UIKit`UIApplicationMain + 159
frame #24: 0x00000001089db0cf ContainerVC2`main + 111 at AppDelegate.swift:12
frame #25: 0x000000010be6d6bd libdyld.dylib`start + 1
and here is the "bt" output after I hit the "continue program execution" button once:
* thread #1: tid = 0x219bd, 0x000000010c206607 libc++abi.dylib`__cxa_throw, queue = 'com.apple.main-thread', stop reason = breakpoint 1.2
frame #0: 0x000000010c206607 libc++abi.dylib`__cxa_throw
frame #1: 0x000000010afca443 libobjc.A.dylib`objc_exception_throw + 341
frame #2: 0x0000000108b7dec2 CoreFoundation`+[NSException raise:format:arguments:] + 98
frame #3: 0x0000000109079455 Foundation`-[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
frame #4: 0x0000000109f65309 UIKit`__67-[UIStoryboardEmbedSegueTemplate newDefaultPerformHandlerForSegue:]_block_invoke + 438
frame #5: 0x0000000109ce05e4 UIKit`-[UIStoryboardSegueTemplate _performWithDestinationViewController:sender:] + 453
frame #6: 0x0000000109ce03ee UIKit`-[UIStoryboardSegueTemplate _perform:] + 82
frame #7: 0x00000001096dc45b UIKit`-[UIViewController performSegueWithIdentifier:sender:] + 99
* frame #8: 0x00000001089d99b3 ContainerVC2`ViewController1.button(sender=0x00007fff57224658, self=0x00007fcddb707cb0) -> () + 131 at ViewController.swift:9
frame #9: 0x00000001089d9a26 ContainerVC2`#objc ViewController1.button(AnyObject) -> () + 54 at ViewController.swift:0
frame #10: 0x000000010953eb6f UIKit`-[UIApplication sendAction:to:from:forEvent:] + 83
frame #11: 0x00000001096bf927 UIKit`-[UIControl sendAction:to:forEvent:] + 67
frame #12: 0x00000001096bfc08 UIKit`-[UIControl _sendActionsForEvents:withEvent:] + 388
frame #13: 0x00000001096be6aa UIKit`-[UIControl touchesBegan:withEvent:] + 414
frame #14: 0x00000001095aabbd UIKit`-[UIWindow _sendTouchesForEvent:] + 1188
frame #15: 0x00000001095ac8d6 UIKit`-[UIWindow sendEvent:] + 3984
frame #16: 0x000000010955a1e1 UIKit`-[UIApplication sendEvent:] + 281
frame #17: 0x0000000109d1502f UIKit`__dispatchPreprocessedEventFromEventQueue + 3314
frame #18: 0x0000000109d0dc4e UIKit`__handleEventQueue + 4879
frame #19: 0x0000000108b1fcb1 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
frame #20: 0x0000000108b04c6c CoreFoundation`__CFRunLoopDoSources0 + 556
frame #21: 0x0000000108b04156 CoreFoundation`__CFRunLoopRun + 918
frame #22: 0x0000000108b03b5d CoreFoundation`CFRunLoopRunSpecific + 285
frame #23: 0x000000010deeca48 GraphicsServices`GSEventRunModal + 161
frame #24: 0x000000010953ce8b UIKit`UIApplicationMain + 159
frame #25: 0x00000001089db0cf ContainerVC2`main + 111 at AppDelegate.swift:12
frame #26: 0x000000010be6d6bd libdyld.dylib`start + 1
UPDATE - prepareforsegue code:
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "seg" {
var vcB: ViewControllerB?
vcB = segue.desinationViewController as? ViewControllerB
}
You don't need to call performSegue for an embed segue. The embed segue is fired automatically when the containing view controller is loaded from the storyboard.
You can use prepareForSegue in the containing view controller to get a reference to the contained view controller (it will be the destinationViewController in the segue). Once you have the reference you can store it in a property and use that to interact with it. Rather than updating the constraint directly, I would suggest that you invoke a function on the view controller that updates its constraint:
class ViewControllerA: UIViewController {
var viewControllerB: ViewControllerB?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "seg" {
self.viewControllerB = segue.destinationViewController as? ViewControllerB
}
}
#IBAction func button(_ sender: AnyObject) {
self.viewControllerB?.doSomethingWithHeight(newHeight)
}
}
class ViewControllerB: UIViewController {
#IBOutlet weak var childViewHeight: NSLayoutConstraint!
func doSomethingWithHeight(newHeight: CGFloat) {
self.childViewHeight.constant = newHeight
}
}
At the point that prepare for segue is called, ViewController B's outlets have not been set yet. They are all nil and so trying to access one will cause a crash.
For what you are trying to do, the dirtiest approach is to change the layoutContraint's constant from inside view controller A by accessing it through the childViewControllers array of view controller A. You will have to cast the first element in the array (assuming you only have one child) into an object of the view controller B class.
The above is a very dirty way to do it, but it will get the job done until you can learn some more.
#IBAction buttonAction(sender: UIButton) {
if let viewControllerB = childViewControllers[0] as? ViewControllerB {
viewControllerB.childViewHeight.constant = 25.0
}
}
Again, this is a very dirty way to do it, but it will get the job done while you are learning the right way.
I've been asked why the above is such a bad idea...
Imagine that you didn't write the app in question, and you are tasked with fixing a bug with the constraint's constant. The first thing you would need to do to fix the bug would be to find all the places that mutate that constant.
In an ideal world, that constant would only be mutated in one place (I have a single method in my ViewController class called updateUI that handles all the IBOutlet mutation.) If that is the case, then fixing the bug will just be a matter of understanding the one function where the constant is getting changed.
The next best situation is that there is only one class that changes the constraint's constant. Then all you have to do to fix the bug is to understand how the class works. A larger task that understanding a single function, but doable.
However, using the code above means that there are multiple classes that adjust the constraint's constant, and if there are two classes doing it, who's to say there aren't more? In this case, fixing the bug requires an understanding of the entire app.
A better way to do it...
Presumably, you have multiple view controllers on the screen that are interconnected in some way through your Model code. The model represents your source of truth. Your two view controllers should be getting notified when the model changes and update themselves and their views accordingly. If you don't have a model representing the abstraction that is affecting these two views, then you should make one.
I am trying to implement a search bar in a UICollectionView as a UICollectionViewReusableView
This way I am not using a UISearchController but I am changing the datasource of the collectionview
In my custom layout I am adding the searchbar this way:
override func prepareLayout() {
super.prepareLayout()
var searchBarAttributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: TeacherSearchbarIdentifier, withIndexPath: NSIndexPath(forItem: 0, inSection: 0))
searchBarAttributes.frame = CGRectMake(0, 0, collectionViewContentSize().width, 44)
searchBarAttributes.zIndex = 100
miscAttributes.append(searchBarAttributes)
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
var attributes = [UICollectionViewLayoutAttributes]()
for (idx, attr) in enumerate(miscAttributes) {
if CGRectIntersection(rect, attr.frame) != CGRectNull {
attributes.append(attr)
}
}
return attributes
}
I am setting the delegate like this:
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
var view = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: kind, forIndexPath: indexPath) as! UICollectionReusableView
if kind == TeacherSearchbarIdentifier {
controller.searchBar = (view as! TeacherSearchView).searchBar
return view
}
}
The variable controller is the UICollectionViewController which implements the UISearchBarDelegate Protocol
The delegate is set in didSet of the searchBar variable. These are my delegates:
override func scrollViewDidScroll(scrollView: UIScrollView) {
self.view.endEditing(true)
}
func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool {
searchBar.setShowsCancelButton(true, animated: true)
return true
}
func searchBarShouldEndEditing(searchBar: UISearchBar) -> Bool {
searchBar.setShowsCancelButton(false, animated: true)
searchBar.resignFirstResponder()
return true
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchBar.setShowsCancelButton(false, animated: true)
searchBar.resignFirstResponder()
}
Now my problem!
When I am tapping on the search bar, the keyboard appears. If I press the cancel button or scroll, it dissappears. Just as I want it to. This also works a second time.
BUT!
If I do this a third time, I get a EXC_BAD_ACCESS:
I tried turning on Enabling Zombie Objects, but no information was provided.
I also tried profiling for Zombie Objects, it just crashes without any noticeable information.
Please help me on how I can resolve this error, or give me further debugging instructions.
EDIT 1:
Here is the output from bt all in the lldb debugger:
* thread #1: tid = 0x228fc, 0x000000019502fbd0 libobjc.A.dylib`objc_msgSend + 16, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1cda8beb8)
frame #0: 0x000000019502fbd0 libobjc.A.dylib`objc_msgSend + 16
frame #1: 0x000000018328b2f4 CoreFoundation`-[__NSDictionaryM objectForKey:] + 84
frame #2: 0x00000001884a21b8 UIKit`-[UICollectionView _visibleViewDictForElementCategory:elementKind:] + 96
frame #3: 0x0000000187ff6644 UIKit`-[UICollectionView _indexPathForView:ofType:] + 160
frame #4: 0x000000018849c3dc UIKit`-[UICollectionView _setIsAncestorOfFirstResponder:] + 792
frame #5: 0x0000000187ed9418 UIKit`+[UIView(Internal) _setIsResponderAncestorOfFirstResponder:startingAtFirstResponder:] + 164
frame #6: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #7: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #8: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #9: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #10: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #11: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #12: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #13: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #14: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #15: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #16: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #17: 0x0000000187f1b194 UIKit`-[UITextField _becomeFirstResponder] + 60
frame #18: 0x000000018800f300 UIKit`-[UISearchBarTextField _becomeFirstResponder] + 108
frame #19: 0x0000000187e9ad28 UIKit`-[UIResponder becomeFirstResponder] + 392
frame #20: 0x0000000187e9b0ac UIKit`-[UIView(Hierarchy) becomeFirstResponder] + 124
frame #21: 0x0000000187f19de4 UIKit`-[UITextField becomeFirstResponder] + 68
frame #22: 0x0000000187fc9fc4 UIKit`-[UITextInteractionAssistant(UITextInteractionAssistant_Internal) setFirstResponderIfNecessary] + 200
frame #23: 0x0000000187fc962c UIKit`-[UITextInteractionAssistant(UITextInteractionAssistant_Internal) oneFingerTap:] + 1736
frame #24: 0x0000000187faf070 UIKit`_UIGestureRecognizerSendActions + 276
frame #25: 0x0000000187e486b4 UIKit`-[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 580
frame #26: 0x00000001882b938c UIKit`___UIGestureRecognizerUpdate_block_invoke662 + 60
frame #27: 0x0000000187e0c418 UIKit`_UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 292
frame #28: 0x0000000187e0a7c4 UIKit`_UIGestureRecognizerUpdate + 2504
frame #29: 0x0000000187e4682c UIKit`-[UIWindow _sendGesturesForEvent:] + 1044
frame #30: 0x0000000187e45ee4 UIKit`-[UIWindow sendEvent:] + 660
frame #31: 0x0000000187e19120 UIKit`-[UIApplication sendEvent:] + 264
frame #32: 0x00000001880ba2b8 UIKit`_UIApplicationHandleEventFromQueueEvent + 15424
frame #33: 0x0000000187e17634 UIKit`_UIApplicationHandleEventQueue + 1716
frame #34: 0x0000000183358240 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
frame #35: 0x00000001833574e4 CoreFoundation`__CFRunLoopDoSources0 + 264
frame #36: 0x0000000183355594 CoreFoundation`__CFRunLoopRun + 712
frame #37: 0x00000001832812d4 CoreFoundation`CFRunLoopRunSpecific + 396
frame #38: 0x000000018ccdf6fc GraphicsServices`GSEventRunModal + 168
frame #39: 0x0000000187e7ef40 UIKit`UIApplicationMain + 1488
* frame #40: 0x00000001000f0798 My-Project`main + 164 at AppDelegate.swift:14
frame #41: 0x00000001956c6a08 libdyld.dylib`start + 4
thread #2: tid = 0x22939, 0x00000001957c4c24 libsystem_kernel.dylib`kevent64 + 8, queue = 'com.apple.libdispatch-manager'
frame #0: 0x00000001957c4c24 libsystem_kernel.dylib`kevent64 + 8
frame #1: 0x000000010083a588 libdispatch.dylib`_dispatch_mgr_invoke + 276
frame #2: 0x000000010082b09c libdispatch.dylib`_dispatch_mgr_thread + 52
thread #8: tid = 0x229d9, 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #0: 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #1: 0x00000001958792dc libsystem_pthread.dylib`_pthread_wqthread + 992
thread #7: tid = 0x229da, 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #0: 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #1: 0x00000001958792dc libsystem_pthread.dylib`_pthread_wqthread + 992
thread #9: tid = 0x229df, 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #0: 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #1: 0x00000001958792dc libsystem_pthread.dylib`_pthread_wqthread + 992
thread #10: tid = 0x229e1, 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #0: 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #1: 0x00000001958792dc libsystem_pthread.dylib`_pthread_wqthread + 992
thread #11: tid = 0x229e2, 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #0: 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #1: 0x00000001958792dc libsystem_pthread.dylib`_pthread_wqthread + 992
thread #12: tid = 0x229e3, 0x00000001957c4e0c libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.NSURLConnectionLoader'
frame #0: 0x00000001957c4e0c libsystem_kernel.dylib`mach_msg_trap + 8
frame #1: 0x00000001957c4c88 libsystem_kernel.dylib`mach_msg + 72
frame #2: 0x0000000183357724 CoreFoundation`__CFRunLoopServiceMachPort + 200
frame #3: 0x0000000183355678 CoreFoundation`__CFRunLoopRun + 940
frame #4: 0x00000001832812d4 CoreFoundation`CFRunLoopRunSpecific + 396
frame #5: 0x0000000182d5e594 CFNetwork`+[NSURLConnection(Loader) _resourceLoadLoop:] + 440
frame #6: 0x00000001842a1db8 Foundation`__NSThread__main__ + 1072
frame #7: 0x000000019587bdc8 libsystem_pthread.dylib`_pthread_body + 164
frame #8: 0x000000019587bd24 libsystem_pthread.dylib`_pthread_start + 160
thread #13: tid = 0x229e6, 0x00000001957df498 libsystem_kernel.dylib`__select + 8, name = 'com.apple.CFSocket.private'
frame #0: 0x00000001957df498 libsystem_kernel.dylib`__select + 8
frame #1: 0x000000018335d128 CoreFoundation`__CFSocketManager + 672
frame #2: 0x000000019587bdc8 libsystem_pthread.dylib`_pthread_body + 164
frame #3: 0x000000019587bd24 libsystem_pthread.dylib`_pthread_start + 160
EDIT 2:
I created a standalone project which produces this error. Just run the project and tap/cancel the searchbar a few times.
Download Project
Video:
Bugreport: rdar://problem/21673802
I came up with a workaround for this in iOS 8. I discovered that the crash only occurred if the kind string of my supplementary view was a Swift string. There was no crash when I used an Objective-C string bridged to Swift. I tried the obvious idea of creating a NSString explicitly in Swift and even tried creating a CFString in Swift and bridging that. However, neither of those efforts were successful.
To easily verify this, try changing TeacherSearchbarIdentifier to an Objective-C string from UIKit like UICollectionElementKindSectionHeader.
A more rigorous workaround would involve creating Objective-C strings for your use case and exposing those to Swift. As an example:
// MyElementKinds.h
#import Foundation;
FOUNDATION_EXPORT NSString *const TeacherSearchbarIdentifier;
// MyElementKinds.m
#import "MyElementKinds.h"
NSString *const TeacherSearchbarIdentifier = #"TeacherSearchbarIdentifier";
I committed a bug report to apple, and they said this:
Apple Developer Relations
Thanks for the update. Upgrading is the solution then.
We are closing this bug report.
If you have questions regarding the resolution of this issue, please
update your bug report with that information.
Please be sure to regularly check new Apple releases for any updates
that might affect this issue.
Basically they don't care about this issue right now because of their upcoming release of iOS 9
I asked what the correct way is to keep compatibility to iOS 8 and the bug report is still open. Let's wait and see!
In my code, I have a line:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!){
if segue.identifier == "seguetotable"{
var tableView: TableViewController = segue.destinationViewController as TableViewController
var callBack: TableViewCallBack = self
tableView.delegate = callBack;
NSLog("segueprepared")
}
}
As you can see, I am trying to use the delegate method to pass parameters. It throws a EXC_BAD_ACCESS (code=1, address=0x14) error at line:
tableView.delegate = callBack;
I searched on google and stackoverflow, it seems to be an error related to the memory management. But I cannot figure out why.
The delegate is defined as
class TableViewController: UITableViewController {
var items: [Thumbnail]=[]
var delegate: TableViewCallBack? = nil
where TableViewCallBack is a protocol defined as
protocol TableViewCallBack {
func updateImage(items: [Thumbnail]);
}
The backtrace is as follows:
thread #1: tid = 0xd6a8a, 0x02004ab8 libswiftCore.dylibswift_dynamicCastClassUnconditional + 56, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
<ul>
<li>frame #0: 0x02004ab8 libswiftCore.dylibswift_dynamicCastClassUnconditional + 56
frame #1: 0x000914d0 FootprintinWorldFootprintinWorld.ViewController.prepareForSegue (segue=0x7bf66130, sender=Some, self=0x7bff37b0)(ObjectiveC.UIStoryboardSegue, sender : Swift.ImplicitlyUnwrappedOptional<Swift.AnyObject>) -> () + 880 at ViewController.swift:53
frame #2: 0x000917b6 FootprintinWorld#objc FootprintinWorld.ViewController.prepareForSegue (FootprintinWorld.ViewController)(ObjectiveC.UIStoryboardSegue, sender : Swift.ImplicitlyUnwrappedOptional) -> () + 86 at ViewController.swift:0
frame #3: 0x010d0b37 UIKit-[UIStoryboardSegueTemplate _perform:] + 199
frame #4: 0x010d0bc5 UIKit-[UIStoryboardSegueTemplate perform:] + 116
frame #5: 0x01c927cd libobjc.A.dylib-[NSObject performSelector:withObject:withObject:] + 84
frame #6: 0x00ab523d UIKit-[UIApplication sendAction:to:from:forEvent:] + 99
frame #7: 0x00e25840 UIKit-[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 139
frame #8: 0x01c927cd libobjc.A.dylib-[NSObject performSelector:withObject:withObject:] + 84
frame #9: 0x00ab523d UIKit-[UIApplication sendAction:to:from:forEvent:] + 99
frame #10: 0x00ab51cf UIKit-[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
frame #11: 0x00be8e86 UIKit-[UIControl sendAction:to:forEvent:] + 69
frame #12: 0x00be92a3 UIKit-[UIControl _sendActionsForEvents:withEvent:] + 598
frame #13: 0x00be850d UIKit-[UIControl touchesEnded:withEvent:] + 660
frame #14: 0x00b0560a UIKit-[UIWindow _sendTouchesForEvent:] + 874
frame #15: 0x00b060e5 UIKit-[UIWindow sendEvent:] + 791
frame #16: 0x00acb549 UIKit-[UIApplication sendEvent:] + 242
frame #17: 0x00adb37e UIKit_UIApplicationHandleEventFromQueueEvent + 20690
frame #18: 0x00aafb19 UIKit_UIApplicationHandleEventQueue + 2206
frame #19: 0x001c41df CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
frame #20: 0x001b9ced CoreFoundation__CFRunLoopDoSources0 + 253
frame #21: 0x001b9248 CoreFoundation__CFRunLoopRun + 952
frame #22: 0x001b8bcb CoreFoundationCFRunLoopRunSpecific + 443
frame #23: 0x001b89fb CoreFoundationCFRunLoopRunInMode + 123
frame #24: 0x0403424f GraphicsServicesGSEventRunModal + 192
frame #25: 0x0403408c GraphicsServicesGSEventRun + 104
frame #26: 0x00ab38b6 UIKitUIApplicationMain + 1526
frame #27: 0x0009a93e FootprintinWorldtop_level_code + 78 at AppDelegate.swift:12
frame #28: 0x0009a97b FootprintinWorldmain + 43 at AppDelegate.swift:0
frame #29: 0x023e9ac9 libdyld.dylib`start + 1
Update:
The bug has been found. The error is caused by line:
var tableView: TableViewController = segue.destinationViewController as TableViewController
Though I still do not know why xcode tells me the bad exec happens two lines later...
The reason is I embedded my TableViewController in a Navigation Controller. Hence, the app cannot convert a navigation controller to a TableViewController (i.e., my custom subclass based on UITableViewController). In order to solve the problem, I just unwrap the TableViewController from the navigation controller. It turns out that if the TableViewController is pushed by a segue from a navigation controller, then it will automatically has the area for navigation bar buttons. So no need to have another navigation controller in this case.
Check this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let controller = segue.destinationViewController as NameOFYourController
}
You are casting it wrong, Surely you have a subclass of UITableViewController where you want to go. Cast it as that controller. Hope this helps.. :)