MKMapView setRegion: animated: crashes the app (edited) - xcode

I have a MKMapView that expands (vertically) on tap (using UITapGestureRecognizer) and fires off an api call on pan (using UIPanGestureRecoginizer).
Everything was working fine, until some time back, where on Panning, the app would crash, with hardly any useful info (or info that I could comprehend)
Exception breakpoints are on, and zombie objects have been enabled. On crashing, it never hits the exception breakpoint!
Here's the log:
(Panning began, panning, panning ended are printed out based on the Pan gestureRecognizer states).
Right after panning ends, the app crashes.
(The map is yet to load all its tiles, and regionDidChangeAnimated is not called yet):
2013-01-17 14:46:04.396 MyApp[13126:c07] Panning Began
2013-01-17 14:46:04.412 MyApp[13126:c07] Panning
2013-01-17 14:46:04.412 MyApp[13126:c07] Panning
2013-01-17 14:46:04.557 MyApp[13126:c07] Panning
2013-01-17 14:46:04.606 MyApp[13126:c07] Panning
2013-01-17 14:46:04.691 MyApp[13126:c07] Panning Ended
2013-01-17 14:46:04.692 MyApp[13126:c07] *** -[MKMapViewPositioningChange hasChanges]: message sent to deallocated instance 0x139f7520
Here's the backtrace i see after the crash:
(lldb) bt
* thread #1: tid = 0x1c03, 0x02a4fa97 CoreFoundation`___forwarding___ + 295, stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
frame #0: 0x02a4fa97 CoreFoundation`___forwarding___ + 295
frame #1: 0x02a4f94e CoreFoundation`_CF_forwarding_prep_0 + 14
frame #2: 0x01244d27 MapKit`-[MKMapView(UserPositioningInternal) _runPositioningChange] + 2037
frame #3: 0x01242dd7 MapKit`-[MKMapView(UserPositioningInternal) _runPositioningChangeIfNeeded:] + 86
frame #4: 0x01240220 MapKit`-[MKMapViewInternal runPositioningChangeIfNeeded] + 50
frame #5: 0x01e2eb90 Foundation`__NSFireTimer + 97
frame #6: 0x02a1f376 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
frame #7: 0x02a1ee06 CoreFoundation`__CFRunLoopDoTimer + 534
frame #8: 0x02a06a82 CoreFoundation`__CFRunLoopRun + 1810
frame #9: 0x02a05f44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #10: 0x02a05e1b CoreFoundation`CFRunLoopRunInMode + 123
frame #11: 0x03c897e3 GraphicsServices`GSEventRunModal + 88
frame #12: 0x03c89668 GraphicsServices`GSEventRun + 104
frame #13: 0x0132d65c UIKit`UIApplicationMain + 1211
frame #14: 0x0001223d MyApp`main + 141 at main.m:16
frame #15: 0x00002fc5 MyApp`start + 53
The crashes go away the moment i take the connection for the PanGestureRecognizer action method.
Is there a way to get rid of this crash while using the gesture recognizers? or is there a way to know that the map was tapped and panned, without using GestureRecognizers?
Any help/questions/answers/comments appreciated!
Update (Jan 19): This doesn't seem to be an issue with the pan gesture recognizer at all. Now I am getting it to crash on after i try to add new annotations to the mapview, call [MapView setRegion: animated:], and crashes just before regionDidChangeAnimated is hit, with the same [MKMapViewPositioningChange hasChanges] log at the point where it crashes.
Update (Jan 23): I think I am quite sure whats happening. there is one chunk of code thats trying to set the region to include all the annotations in the visible rect of the MKMapView, and a few other locations, where I am calling [myMapView removeAnnotations:[myMapView annotations]]. And, my guess is that these two actions end up in a nasty mid-air collision, leaving no trail as to what lead to a crash. Will update the question with an answer if my hunch-fix passes QA

As I had guessed earlier (second update to the question), this was an issue with trying the add set the map region to show all annotations, and removing all annotations simultaneously. if you are calling setRegion: animated: , make sure to check if the mapView has at least one annotation.
Also, it'll be helpful to use the following piece of code judiciously, especially if you are doing any type of animations on the map based on the annotations.
[MKMapView removeAnnotations:[MKMapView annotations]];

Related

NSDrawer causes crash when added to App Window

I'm trying to programmatically add an NSDrawer to my app's main window (which also has an NSOutlineViewwhich was setup in IB):
Ivar:
var dd: NSDrawer? = nil
Then, when a disclosure triangle button is clicked:
if dd == nil {
var drawer_rect = NSInsetRect(self.window.frame, 30, 30).size
drawer_rect.height = 150
dd = NSDrawer.init(contentSize: drawer_rect, preferredEdge: NSRectEdge.minY)
dd!.contentView = self.status_scroll
dd!.parentWindow = self.window
}
So when the user tries to 'disclose' the drawer, the above code creates an NSDrawer and then displays it. It all works fine but Xcode dumps the following out as the parentWindow is set:
[General] ERROR: Setting <NSOutlineView: 0x100f0b9b0> as the first responder for window <NSDrawerWindow: 0x100fc8900>, but it is in a different window (<NSWindow: 0x6080001e0600>)! This would eventually crash when the view is freed. The first responder will be set to nil.
(
0 AppKit 0x00007fff9fc289cf -[NSWindow _validateFirstResponder:] + 557
1 AppKit 0x00007fff9f3a374c -[NSWindow _setFirstResponder:] + 31
2 AppKit 0x00007fff9f90c35b -[NSDrawerWindow _setParentWindow:] + 64
3 AppKit 0x00007fff9f90b666 -[NSDrawer(DrawerInternals) _doSetParentWindow:] + 382
4 AppKit 0x00007fff9f907786 -[NSDrawer setParentWindow:] + 78
Comment out the setting of the parentWindow and nothing gets dumped to the console.
NSDrawer is deprecated as per Apple documentation. You should consider a different design. If you still use NSDrawer, you may face such issues.

NSTextView inspector bar crash on Sierra 10.12

Is anyone else seeing a crash calling setUsesInspectorBar on NSTextView for Sierra (release build)? This code worked just fine on 10.11.5 but crashes in AppKit on Sierra. I thought it was a beta version bug I'm still getting it on the full release.
Here's the back trace from lldb.
(lldb) bt
* thread #1: tid = 0x76deb, 0x9ecfe013 libobjc.A.dylib`objc_msgSend + 19, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xa007cc0f)
* frame #0: 0x9ecfe013 libobjc.A.dylib`objc_msgSend + 19
frame #1: 0x95c5f861 Foundation`releasingRelinquish + 29
frame #2: 0x95c22636 Foundation`-[NSConcreteMapTable removeObjectForKey:] + 127
frame #3: 0x92fbec6e AppKit`-[NSStackViewContainer removeView:] + 102
frame #4: 0x92798554 AppKit`-[NSStackView _insertView:atIndex:inGravity:animated:] + 212
frame #5: 0x9279847b AppKit`-[NSStackView insertView:atIndex:inGravity:] + 40
frame #6: 0x9279839b AppKit`-[NSStackView addView:inGravity:] + 78
frame #7: 0x92f5ec2c AppKit`-[__NSInspectorBarView addItem:] + 71
frame #8: 0x929281c1 AppKit`__23-[NSInspectorBar _tile]_block_invoke + 303
frame #9: 0x94566871 CoreFoundation`__53-[__NSArrayM enumerateObjectsWithOptions:usingBlock:]_block_invoke + 81
frame #10: 0x94566717 CoreFoundation`-[__NSArrayM enumerateObjectsWithOptions:usingBlock:] + 167
frame #11: 0x945665f5 CoreFoundation`-[NSArray enumerateObjectsUsingBlock:] + 53
frame #12: 0x92925e95 AppKit`-[NSInspectorBar _tile] + 484
frame #13: 0x92924e3d AppKit`-[NSInspectorBar _update] + 224
frame #14: 0x92630b28 AppKit`-[NSTextView updateInspectorBar] + 71
frame #15: 0x9263159b AppKit`-[NSTextView updateRuler] + 2622
frame #16: 0x9292440f AppKit`-[NSTextView(NSSharing) setUsesInspectorBar:] + 350
frame #17: 0x0014eef4 DockShelf`"-[TTextEditorWindowController awakeFromNib]"(self=0x0073ecc0, _cmd="awakeFromNib") + 116 at UTextEditor_2.pas:124
This is a bug in AppKit with 32-bit apps. Unfortunately, not workaround-able (without removing inspector bar support) and will require a fix in AppKit.
This should be fixed with 10.12.2
Try to remove NSTextView component in IB and then insert it back again from component's palette. It is possible that your old XIB file contains some keywords which are not recognised/compiled properly into NIB file and Sierra cannot process file.

Swift: Breakpoint in CoreData library

XCode 6 Beta 3 using Swift.
In my App I use CoreData. When I run my App in simulator, XCode pops up the debugger with a breakpoint set somewhere in the CoreData library (see screenshot). This happens on several CoreData functions, for example when inserting new records or fetching records from an entity. The breakpoint position is always the same.
This is extremely annoying. When my App fetches 10 records from an entity I have to push the continue program execution button 10 times.
Because this breakpoint is set somewhere in machine code, the breakpoint inspector does not show any breakpoints so I cannot delete it.
Does anyone know how to get rid of it?
Many thanks.
Edit:
backtrace-output:
(lldb) bt
* thread #1: tid = 0x1d68b0, 0x000000010a2f7fcd libswift_stdlib_core.dylibswift_dynamicCastClassUnconditional + 77, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
* frame #0: 0x000000010a2f7fcd libswift_stdlib_core.dylibswift_dynamicCastClassUnconditional + 77
frame #1: 0x000000010a0fbb85 GPS TrackGPS_Track.TrackListTableViewController.tableView (tableView=<unavailable>)(Swift.ImplicitlyUnwrappedOptional<ObjectiveC.UITableView>, cellForRowAtIndexPath : Swift.ImplicitlyUnwrappedOptional<ObjectiveC.NSIndexPath>) -> Swift.Optional<ObjectiveC.UITableViewCell> + 1125 at TrackListTableViewController.swift:53
frame #2: 0x000000010a0fc937 GPS Track#objc GPS_Track.TrackListTableViewController.tableView (GPS_Track.TrackListTableViewController)(Swift.ImplicitlyUnwrappedOptional, cellForRowAtIndexPath : Swift.ImplicitlyUnwrappedOptional) -> Swift.Optional + 87 at TrackListTableViewController.swift:0
frame #3: 0x000000010bc2f218 UIKit-[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 508
frame #4: 0x000000010bc0f340 UIKit-[UITableView _updateVisibleCellsNow:isRecursive:] + 2845
frame #5: 0x000000010bc24fea UIKit-[UITableView layoutSubviews] + 213
frame #6: 0x000000010bbb1ebd UIKit-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 519
frame #7: 0x000000010b9c9598 QuartzCore-[CALayer layoutSublayers] + 150
frame #8: 0x000000010b9be1be QuartzCoreCA::Layer::layout_if_needed(CA::Transaction*) + 380
frame #9: 0x000000010b9be02e QuartzCoreCA::Layer::layout_and_display_if_needed(CA::Transaction*) + 24
frame #10: 0x000000010b92cf16 QuartzCoreCA::Context::commit_transaction(CA::Transaction*) + 242
frame #11: 0x000000010b92e022 QuartzCoreCA::Transaction::commit() + 390
frame #12: 0x000000010b92e68d QuartzCoreCA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 89
frame #13: 0x000000010ab52927 CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
frame #14: 0x000000010ab52880 CoreFoundation__CFRunLoopDoObservers + 368
frame #15: 0x000000010ab480d3 CoreFoundation__CFRunLoopRun + 1123
frame #16: 0x000000010ab47a06 CoreFoundationCFRunLoopRunSpecific + 470
frame #17: 0x000000010e9e9abf GraphicsServicesGSEventRunModal + 161
frame #18: 0x000000010bb39cf8 UIKitUIApplicationMain + 1282
frame #19: 0x000000010a0e6a5d GPS Tracktop_level_code + 77 at AppDelegate.swift:36
frame #20: 0x000000010a0e6a9a GPS Trackmain + 42 at AppDelegate.swift:0
frame #21: 0x000000010d2e7145 libdyld.dylib`start + 1
(lldb)
I tracked it down further: The problem only occurs when using custom object classes for the entities. Example:
// User class, defined in User.swift
class User: NSManagedObject {
#NSManaged var name: String
#NSManaged var firstname: String
}
// --------------
// code somewhere else
let users = moc.executeFetchRequest(fetchRequest, error: &error)
for object in users {
let user = object as User // <-- breakpoint fired here
println(user.name)
}
}
SOLUTION:
One need to make the custom object class visible to Objective C using the #objc directive:
// User class, defined in User.swift
#objc(User) // <-- required!
class User: NSManagedObject {
#NSManaged var name: String
#NSManaged var firstname: String
}
Thanks to all for your help!
Do you have an All Exception breakpoint set?
Contrary to Apple's best practices CoreData uses exceptions in the normal flow of control.
If you add exception breakpoints you may break in CoreData. The solution is to remove or disable the exception breakpoint.
While the above answers all are technically correct
#zisoft is right, however if you're using custom NSManagedObject classes then you should always use #objc(User), not just because of this break point.
#Zaph may work also, as you're essentially not listening and if indeed it's a bug it should stop it from appearing
However you may still hit this kind of break point if you're not type checking. I suspect it's a breakpoint in the beta 4 but will become a crash in the next beta.
I solved the issue in my code as I was hitting on returning the managed object received from insertNewObjectForEntityForName as AnyObject and later saying as myclass when I used it. Fine as I knew it was my class. but actualy should have done something like this
func createMyEntity() -> MyClass{
if let entity : MyClass = NSEntityDescription.insertNewObjectForEntityForName("MyClass", inManagedObjectContext: self.managedObjectContext) as? MyClass
{
return entity;
}
return nil;
}
Obviously that's just one example, but if you're the hitting the break point in other places then hopefully this a good reference.
Not withstanding this still may just be a bug in beta 4 of xcode, but this is safer anyway.
Update -- It also checking that your data model class name matches as it later through a warning here an this may also be why the breakpoint was hit.
I fixed my version of this problem based on info in https://devforums.apple.com/message/1016337#1016337
make the NSManagedObject-derived class and its relevant properties public
do not include its source file in the test target's Compile Sources
import the app target in the test file -- e.g., import MyApp in MyClassTests.swift
In your Core Data *.xcdatamodeld file, prefix your entity's class name with your app name. It should look something like this when you're done:
Thanks the last helped!!!
make the NSManagedObject-derived class and its relevant properties public
do not include its source file in the test target's Compile Sources
import the app target in the test file -- e.g., import MyApp in MyClassTests.swift
Following helped me !
If I undone one of this settings the breakpoint error comes again !
You have to set for your Entity-Model in your *Model.xcdatamodeld in property "Class" the same Name example: Name=Chat Class=Chat
You have to add Code #objc(yourClass) above your class
Pictures 1:
http://i.stack.imgur.com/xoxtu.png
Pictures 2:
http://i.stack.imgur.com/LkYYq.png
For anyone using Xcode 6.2
Make #objc changes to your class i.e #objc(className)
Next go to *.xcdatamodeld -> Configurations (Default if nothing specified) -> add class against entity

How to tell if an application is in modal state

I want to be able to tell if my application is currently in a "modal" state.
I know that if it is in this state using Cocoa's functions, I could tell by checking where [[NSApplication sharedApplication] modalWindow] returns nil or not.
But it could also be in modal state using Carbon's functions (RunAppModalLoopForWindow etc), and then Cocoa's modalWindow does not tell us whether the application is modal.
Unfortunately, I don't have the choice to avoid Carbon as my app hosts old third party plugins which do use it.
Here's part of an example stack trace in a modal state due to carbon:
frame #12: 0x93ede739 CoreFoundation`__CFRunLoopRun + 1897
frame #13: 0x93eddd5a CoreFoundation`CFRunLoopRunSpecific + 394
frame #14: 0x93eddbbb CoreFoundation`CFRunLoopRunInMode + 123
frame #15: 0x930cee2d HIToolbox`RunCurrentEventLoopInMode + 259
frame #16: 0x930cebb2 HIToolbox`ReceiveNextEventCommon + 526
frame #17: 0x93119c4a HIToolbox`AcquireNextEventInMode + 75
frame #18: 0x93269aea HIToolbox`_AcquireNextEvent + 58
frame #19: 0x932585dc HIToolbox`_RunAppModalLoop + 168
frame #20: 0x932584ee HIToolbox`RunAppModalLoopForWindow + 130
I could trace the stack and see that _RunAppModalLoop is there, but I don't like this solution.
You can try checking the output from GetWindowModality([[NSApp keyWindow] windowRef], ...) and/or the same applied to the -mainWindow.
You can see if -[NSRunLoop currentMode] is NSDefaultRunLoopMode.
However, you might get a different answer with a question more specific to the problem you're trying to solve.
This can be done by enumerating all the app's windows and checking if they are modal by using GetWindowModality.
bool isAnyCarbonWindowModal()
{
for (
WindowRef win = GetFrontWindowOfClass(kAllWindowClasses, true);
win != nullptr;
win = GetNextWindowOfClass(win, kAllWindowClasses, true))
{
WindowModality modalKind;
WindowRef unavailableWindow;
GetWindowModality(win, &modalKind, &unavailableWindow);
if (kWindowModalityAppModal == modalKind)
return true;
}
return false;
}

How to track down the line that's causing a runtime error?

My app is crashing with this error message:
'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: 0)'
and I am trying to find where this is occuring in my code. I have set NSZombiesEnabled in the environment variables, however it's pretty hard to figure out the location. Any idea on how to debug?
I typed in bt and here's what I see:
frame #0: 0x30d1832c libsystem_kernel.dylib`__pthread_kill + 8
frame #1: 0x3597d20e libsystem_c.dylib`pthread_kill + 54
frame #2: 0x3597629e libsystem_c.dylib`abort + 94
frame #3: 0x35055f6a libc++abi.dylib`abort_message + 46
frame #4: 0x3505334c libc++abi.dylib`_ZL17default_terminatev + 24
frame #5: 0x36c38356 libobjc.A.dylib`_objc_terminate + 146
frame #6: 0x350533c4 libc++abi.dylib`_ZL19safe_handler_callerPFvvE + 76
frame #7: 0x35053450 libc++abi.dylib`std::terminate() + 20
frame #8: 0x35054824 libc++abi.dylib`__cxa_rethrow + 88
frame #9: 0x36c382a8 libobjc.A.dylib`objc_exception_rethrow + 12
frame #10: 0x3428d50c CoreFoundation`CFRunLoopRunSpecific + 404
frame #11: 0x3428d36c CoreFoundation`CFRunLoopRunInMode + 104
frame #12: 0x3826f438 GraphicsServices`GSEventRunModal + 136
frame #13: 0x36d27cd4 UIKit`UIApplicationMain + 1080
frame #14: 0x00051cdc AppName`main + 80 at main.m:16
Add exceptions as a breakpoint. Assuming Xcode 4+...
At the top of the navigator frame (where you view files and such), you will see a little icon that looks like a sideways arrow.
That will show the breakpoint navigator. At the bottom of that view, click the + to add a breakpoint.
Click on "Add exception breakpoint..."
The default option is probably fine... you want to break on throw of all exceptions.
Now, when you run, you will get a breakpoint anywhere your app throws an exception.
Is the error happening in your testing? Are you seeing it from crash logs from iTunes Connect?
If you are able to reproduce it locally, run the scenario to duplicate the error and when the debugger becomes active, type "bt" at the (gdb) prompt in the Console for a stacktrace with a line number.
Try to add this part of code in your AppDelegate :
void uncaughtExceptionHandler(NSException *exception);
void uncaughtExceptionHandler(NSException *exception) {
NSLog(#"CRASH: %#", exception);
NSLog(#"Stack Trace: %#", [exception callStackSymbols]);
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
// your previous code here
return YES;
}
Next time your error occurs, you should have some additional infos on the crash.

Resources