Home Features Docs Blog Support GitHub

Libc++abi.dylib: terminating with uncaught exception of type ObjCException [SOLVED]


(Leejjon) #1

Hi,

The exception message in the title has been bugging my code for a while. It only occurred 70% of the time. I also tried to isolate the problem in a small project to post it here and guess what, it didn’t occur (so can it be a memory related thing).

There is no stacktrace, just the following message in the log:

libc++abi.dylib: terminating with uncaught exception of type ObjCException

By placing a lot of logging I managed to find the lines where it broke. I have tried to put try catch blocks around everything to catch it, but the entire program just freezes and you cannot do anything anymore.

This is my code:

private void selectContacts(Set<String> alreadyExistingPlayers, CNContactStore contactStore) {
    // TODO: Handle the error. Currently everything I tried to do with the error object didn't work though...
    Ptr<NSError> error = PtrFactory.newObjectReference(NSError.class);
    // TODO: Also retrieve the last name. But for some reason that results in an ObjCException so I sticked with only the first name now...
    NSArray<?> keysToFetch = NSArray.arrayWithObject(Contacts.CNContactGivenNameKey());//, Contacts.CNContactFamilyNameKey());
    CNContactFetchRequest request = CNContactFetchRequest.alloc().initWithKeysToFetch(keysToFetch);

    // TODO: Figure out why we keep getting the "libc++abi.dylib: terminating with uncaught exception of type ObjCException"
    contactStore.enumerateContactsWithFetchRequestErrorUsingBlock(request, error, new CNContactStore.Block_enumerateContactsWithFetchRequestErrorUsingBlock() {
        @Override
        public void call_enumerateContactsWithFetchRequestErrorUsingBlock(CNContact contact, BoolPtr stop) {
            String name = contact.givenName(); // + contact.familyName();
            if (!(name.length() == 0) && !alreadyExistingPlayers.contains(name)) {
                names.add(name);
                /***************************
                 * If I add any code here to add the name directly to the UI, we sometimes get an ObjCException.
                 ***************************/
                someUILabel.setText(name); // CRASH
            }
        }
    });
}

Do you guys see anything wrong with my code?

I have found a work around for this so this is not a high priority thing for me. I can provide a full sample to reproduce it if necessary.

PS: I use the moe 1.3.8, gradle plugin 1.3.12 and libgdx 1.9.6 and I test on an iPhone 5s


(Roland Vigh - Migeran) #2

Hi!

Please try this code:

Globals.dispatch_async(Globals.dispatch_get_main_queue(), new Globals.Block_dispatch_async() {
                                @Override
                                public void call_dispatch_async() {
                                    someUILabel().setText(name);
                                }
                            }
                    );

Best Regards,
Roland


(Leejjon) #3

That seems to work, thanks. I did work around it myself by launching the contacts method from a different thread and have the original thread do a Thread.sleep(200); but obviously that was an ugly workaround.

So I guess you have to do UI updates from a main queue like explained here also:


(Gergely Kis - Migeran) #4

Yes, in most modern UI frameworks (this includes Android, iOS and even everybody’s favorite Swing :slight_smile: ), UI updates need to be done from a designated main / UI event thread.


(Leejjon) #5

Also found out that libgdx has the Gdx.postRunnable(Runnable runnable); Method which puts the Runnable in a queue that will be ran before the render method:

That should also solve my problem.