Crash with RestKit when issuing multiple requests in quick succession - objective-c

I have a button with two buttons which start the download of some data from a web server with RestKit.
Now if the user taps the two buttons repeatedly in quick succession my app crashes and produces the crash log below.
I initiate my requests like so:
-(void)loadDataAtPath:(NSString *)path completion:(ResultArrayBlock)completionBlock failed:(ResultFailedBlock)failedBlock
{
RKObjectMapping *groupMapping = [Group mapping];
[self.objectManager.mappingProvider setMapping:groupMapping forKeyPath:#"groups.group"];
[self.objectManager.mappingProvider setObjectMapping:groupMapping forKeyPath:path];
[self.objectManager loadObjectsAtResourcePath:path usingBlock:^(RKObjectLoader *loader) {
loader.onDidLoadObjects = ^(NSArray *array){
// Do the reverse mapping of the group
for (Group *c in array) {
for(Person *p in c.persons){
p.group = c;
}
}
completionBlock(array);
};
loader.onDidFailWithError = failedBlock;
}];
}
I first thought that the problem was the for-loop where I do some after-mapping setup of my data, but the problem still persists even when commenting the for-loop.
Curiously this problem does not occur in the simulator even when I switch on the Network Link Conditioner.prefpane
The crash
When I debug this on the device I get the following on the console.
[PLCrashReport] Terminated stack walking early: Corrupted frame
[PLCrashReport] Terminated stack walking early: Corrupted frame
The crash log looks like this:
Application Specific Information:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFDictionary: 0x3c14a0> was mutated while being enumerated.'
Last Exception Backtrace:
0 CoreFoundation 0x3734e88f __exceptionPreprocess + 162
1 libobjc.A.dylib 0x35053259 objc_exception_throw + 32
2 CoreFoundation 0x3734e3b3 __NSFastEnumerationMutationHandler + 162
3 MyApp 0x0008f5bf -[RKObjectMapper performKeyPathMappingUsingMappingDictionary:] + 407
4 MyApp 0x0008fa45 -[RKObjectMapper performMapping] + 673
5 MyApp 0x0008ac7d -[RKObjectLoader mapResponseWithMappingProvider:toObject:inContext:error:] + 1045
6 MyApp 0x0008b04f -[RKObjectLoader performMapping:] + 575
7 MyApp 0x0008b22b __47-[RKObjectLoader performMappingInDispatchQueue]_block_invoke_0 + 247
8 libdispatch.dylib 0x3046ec59 _dispatch_call_block_and_release + 12
9 libdispatch.dylib 0x30479cab _dispatch_queue_drain + 274
10 libdispatch.dylib 0x30479b19 _dispatch_queue_invoke$VARIANT$up + 36
11 libdispatch.dylib 0x3047a78b _dispatch_worker_thread2 + 214
12 libsystem_c.dylib 0x33bbddfb _pthread_wqthread + 294
13 libsystem_c.dylib 0x33bbdcd0 start_wqthread + 8

As #PhillipMills suggested, you can easily see the answer when you look inside performKeyPathMappingUsingMappingDictionary. Your problem is repeatedly setting the mapping with these lines:
[self.objectManager.mappingProvider setMapping:groupMapping forKeyPath:#"groups.group"];
[self.objectManager.mappingProvider setObjectMapping:groupMapping forKeyPath:path];
If you call this line while the response is being mapping it triggers the error because you are changing the same dictionary it is trying to fast enumerate over.
Normally, you would set the mapping somewhere in the initial configuration and NOT each time like this.

Related

Unrecognized selector sent to class when running a react-native app as a view controller in another app

We have a react-native app that we develop as a standalone app and then we have a pod that exports the app with a native entry point. Part of our app uses react-native-awesome-card-io which works fine when we run the the app as a standalone piece (metro bundler). We use cocoa pods to manage the dependencies that react-native link usually does for us. We were using react-native: 57.8 but had to upgrade to 59.0 in order to be able to integrate our plugin into android apps without having to add filtering for 32/64 bit. Anyways we have an example app that just has a button and when the button is pressed, the action takes the view controller we created and presentModalViewController is triggered. The issue came up after we upgraded react-native, when we call the scanCard function on press in our react-native js, The following error comes up
It worked fine previously and it works if we run the app as a standalone react-native app but when we integrate it, the issue comes up. Here is how we instantiate the react-native plugin.
NOTE: it fails for both our objective-c and swift example consumer apps. I haven't found anything online.
How we load our viewcontroller in our sample app
- (IBAction)launchPaciolanSDKAction:(UIButton *)sender {
printf("Launching PaciolanSDK ...");
UIViewController *viewController = nil;
viewController = [[PaciolanSDKViewController alloc] initWithString::""];
[self presentModalViewController:viewController animated:YES];
}
Error:
Exception 'Please add -ObjC to 'Other Linker Flags' in your project settings. (+[NSObject testForObjCLinkerFlag]: unrecognized selector sent to class 0x1dbbd7eb0)' was thrown while invoking scanCard on target CardIOModule with params (
{
hideCardIOLogo = 1;
requireCardholderName = 1;
suppressManualEntry = 1;
usePaypalActionbarIcon = 0;
},
3544,
3545
)
callstack: (
0 CoreFoundation 0x00000001a1cf5ebc <redacted> + 252
1 libobjc.A.dylib 0x00000001a0ec5a50 objc_exception_throw + 56
2 CoreFoundation 0x00000001a1bfc484 <redacted> + 0
3 RNAwesomeCardIO 0x000000010385bf6c -[CardIOPaymentViewController initWithPaymentDelegate:scanningEnabled:] + 660
4 RNAwesomeCardIO 0x00000001038598bc -[RCTCardIOModule scanCard:resolver:rejecter:] + 236
5 CoreFoundation 0x00000001a1cfd610 <redacted> + 144
6 CoreFoundation 0x00000001a1bdb340 <redacted> + 292
7 CoreFoundation 0x00000001a1bdbf24 <redacted> + 60
8 React 0x0000000103ec3d10 -[RCTModuleMethod invokeWithBridge:module:arguments:] + 2064
9 React 0x0000000103ecfe2c _ZN8facebook5reactL11invokeInnerEP9RCTBridgeP13RCTModuleDatajRKN5folly7dynamicE + 664
10 React 0x0000000103ecf99c _ZZN8facebook5react15RCTNativeModule6invokeEjON5folly7dynamicEiENK3$_0clEv + 144
11 React 0x0000000103ecf900 ___ZN8facebook5react15RCTNativeModule6invokeEjON5folly7dynamicEi_block_invoke + 28
12 libdispatch.dylib 0x000000010494f824 _dispatch_call_block_and_release + 24
13 libdispatch.dylib 0x0000000104950dc8 _dispatch_client_callout + 16
14 libdispatch.dylib 0x000000010495ea78 _dispatch_main_queue_callback_4CF + 1360
15 CoreFoundation 0x00000001a1c85ce4 <redacted> + 12
16 CoreFoundation 0x00000001a1c80bac <redacted> + 1964
17 CoreFoundation 0x00000001a1c800e0 CFRunLoopRunSpecific + 436
18 GraphicsServices 0x00000001a3ef9584 GSEventRunModal + 100
19 UIKitCore 0x00000001cefe0c00 UIApplicationMain + 212
20 sample 0x0000000102f0e1fc main + 124
21 libdyld.dylib 0x00000001a173ebb4 <redacted> + 4
)
Check out your parameters and headers that you are sending to api.This error mostly occur when we send wrong parameters.

Why doesn't #try...#catch work with -[NSFileHandle writeData]?

I have a method that is similar to the tee utility. It receives a notification that data has been read on a pipe, and then writes that data to one or more pipes (connected to subordinate applications). If a subordinate app crashes, then that pipe is broken, and I naturally get an exception, which is then handled in a #try...#catch block.
This works most of the time. What I'm puzzled by is that occasionally, the exception crashes the app entirely with an uncaught exception, and pointing to the writeData line . I haven't been able to figure out what the pattern is on when it crashes, but why should it ever NOT be caught? (Note this is not executing inside the debugger.)
Here's the code:
//in setup:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(tee:) name:NSFileHandleReadCompletionNotification object:fileHandle];
-(void)tee:(NSNotification *)notification
{
// NSLog(#"Got read for tee ");
NSData *readData = notification.userInfo[NSFileHandleNotificationDataItem];
totalDataRead += readData.length;
// NSLog(#"Total Data Read %ld",totalDataRead);
NSArray *pipes = [teeBranches objectForKey:notification.object];
if (readData.length) {
for (NSPipe *pipe in pipes {
#try {
[[pipe fileHandleForWriting] writeData:readData];
}
#catch (NSException *exception) {
NSLog(#"download write fileHandleForWriting fail: %#", exception.reason);
if (!_download.isCanceled) {
[_download rescheduleOnMain];
NSLog(#"Rescheduling");
}
return;
}
#finally {
}
}
}
I should mention that I have set a signal handler in my AppDelegate>appDidFinishLaunching:
signal(SIGPIPE, &signalHandler);
signal(SIGABRT, &signalHandler );
void signalHandler(int signal)
{
NSLog(#"Got signal %d",signal);
}
And that does execute whether the app crashes or the signal is caught.
Here's a sample crash backtrace:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Application Specific Information:
*** Terminating app due to uncaught exception 'NSFileHandleOperationException', reason: '*** -[NSConcreteFileHandle writeData:]: Broken pipe'
abort() called
terminating with uncaught exception of type NSException
Application Specific Backtrace 1:
0 CoreFoundation 0x00007fff838cbbec __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff90e046de objc_exception_throw + 43
2 CoreFoundation 0x00007fff838cba9d +[NSException raise:format:] + 205
3 Foundation 0x00007fff90a2be3c __34-[NSConcreteFileHandle writeData:]_block_invoke + 81
4 Foundation 0x00007fff90c53c17 __49-[_NSDispatchData enumerateByteRangesUsingBlock:]_block_invoke + 32
5 libdispatch.dylib 0x00007fff90fdfb76 _dispatch_client_callout3 + 9
6 libdispatch.dylib 0x00007fff90fdfafa _dispatch_data_apply + 110
7 libdispatch.dylib 0x00007fff90fe9e73 dispatch_data_apply + 31
8 Foundation 0x00007fff90c53bf0 -[_NSDispatchData enumerateByteRangesUsingBlock:] + 83
9 Foundation 0x00007fff90a2bde0 -[NSConcreteFileHandle writeData:] + 150
10 myApp 0x000000010926473e -[MTTaskChain tee:] + 2030
11 CoreFoundation 0x00007fff838880dc __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
12 CoreFoundation 0x00007fff83779634 _CFXNotificationPost + 3140
13 Foundation 0x00007fff909bb9b1 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
14 Foundation 0x00007fff90aaf8e6 _performFileHandleSource + 1622
15 CoreFoundation 0x00007fff837e9ae1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
16 CoreFoundation 0x00007fff837dbd3c __CFRunLoopDoSources0 + 476
17 CoreFoundation 0x00007fff837db29f __CFRunLoopRun + 927
18 CoreFoundation 0x00007fff837dacb8 CFRunLoopRunSpecific + 296
19 HIToolbox 0x00007fff90664dbf RunCurrentEventLoopInMode + 235
20 HIToolbox 0x00007fff90664b3a ReceiveNextEventCommon + 431
21 HIToolbox 0x00007fff9066497b _BlockUntilNextEventMatchingListInModeWithFilter + 71
22 AppKit 0x00007fff8acf5cf5 _DPSNextEvent + 1000
23 AppKit 0x00007fff8acf5480 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 194
24 AppKit 0x00007fff8ace9433 -[NSApplication run] + 594
25 AppKit 0x00007fff8acd4834 NSApplicationMain + 1832
26 myApp 0x00000001091b16a2 main + 34
27 myApp 0x00000001091ab864 start + 52
So, the nice folks at Crashlytics were able to help me here. To quote them:
Here's the story:
The pipe dies because the child process crashes. The very next read/write will cause a fault.
That write occurs, which results in a SIGPIPE (not a runtime exception).
If that SIGPIPE is masked/ignored, NSFileHandle checks errno and creates a runtime exception which it throws.
A function deeper than your tee: method has wrapped this write in a #try/#catch (proved by setting a breakpoint on __cxa_begin_catch)
That function, which turns out to be "_dispatch_client_callout", which makes a call to objc_terminate, which effectively kills the
process.
Why does _dispatch_client_callout do this? I'm not sure, but you can
see the code here:
http://www.opensource.apple.com/source/libdispatch/libdispatch-228.23/src/object.m
Unfortunately, AppKit has a really poor track record of being a good
citizen in the face of runtime exceptions.
So, you are right that NSFileHandle raises a runtime exception about
the pipe dying, but not before a signal is raised that kills the
process. Others have encountered this exact issue (on iOS, which has
much better semantics about runtime exceptions).
How can I catch EPIPE in my NSFIleHandle handling?
In short, I don't believe it is possible for you to catch this
exception. But, by ignoring SIGPIPE and using lower-level APIs to
read/write to this file handle, I believe you can work around this. As
a general rule, I'd recommend against ignoring signals, but in this
case, it seems reasonable.
Thus the revised code is now:
-(void)tee:(NSNotification *)notification {
NSData *readData = notification.userInfo[NSFileHandleNotificationDataItem];
totalDataRead += readData.length;
// NSLog(#"Total Data Read %ld",totalDataRead);
NSArray *pipes = [teeBranches objectForKey:notification.object];
if (readData.length) {
for (NSPipe *pipe in pipes ) {
NSInteger numTries = 3;
size_t bytesLeft = readData.length;
while (bytesLeft > 0 && numTries > 0 ) {
ssize_t amountSent= write ([[pipe fileHandleForWriting] fileDescriptor], [readData bytes]+readData.length-bytesLeft, bytesLeft);
if (amountSent < 0) {
NSLog(#"write fail; tried %lu bytes; error: %zd", bytesLeft, amountSent);
break;
} else {
bytesLeft = bytesLeft- amountSent;
if (bytesLeft > 0) {
NSLog(#"pipe full, retrying; tried %lu bytes; wrote %zd", (unsigned long)[readData length], amountSent);
sleep(1); //probably too long, but this is quite rare
numTries--;
}
}
}
if (bytesLeft >0) {
if (numTries == 0) {
NSLog(#"Write Fail4: couldn't write to pipe after three tries; giving up");
}
[self rescheduleOnMain];
}
}
}
}
I know this doesn't do much to answer why the exception catching seems broken, but I hope that this is a helpful answer to workaround the issue.
I faced a similar issue trying to read/write to a socket wrapped in an NSFileHandle. I worked around it by testing the pipe availability directly with the fileDescriptor like so
- (BOOL)socketIsValid
{
return (write([fh fileDescriptor], NULL, 0) == 0);
}
then I tested with that method before attempting to call writeData:.

NSInvalidUnarchiveOperationException when unarchieving custom class

edit:
By adding QCAnnonce* a = [[QCAnnonce alloc] init];In my code somewhere before the function call, I solved the problem, so I guess that I "introduced the class to the runtime". But I have now a warning saying that "a" is unused, so is there a runtime function I can use to "introduce the class to the runtime"?
I am trying to create a client-server application. The objects are archived and unarchived for transmission using NSKeyed(Un)Archiver. Most of my objects are transmitted without any problem, but one of them raise an NSInvalidUnarchiveOperationException.
The exception is called before the breakpoint I placed in initWithCoder:.
I have tried to archive/unarchive before sending and this works well, so it shouldn't be an issue with initWithCoder.
I have tried to create a client in my server app (not in a separate app as my client) and he can decode the object. I can't see any difference between my client and this new client except that they are not in the same app.
The best guess I have is this part of the apple doc:
The delegate may, for example, load some code to introduce the class
to the runtime and return the class, or substitute a different class
object. If the delegate returns nil, unarchiving aborts and the method
raises an NSInvalidUnarchiveOperationException.
But I have no idea what "introduce the class to the runtime" means.
Here are this object methods for encoding/decoding:
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (self) {
a_listeAnnonces = [aDecoder decodeObjectForKey:#"Cartes"];
a_points = [aDecoder decodeIntForKey:#"Points"];
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:a_listeAnnonces forKey:#"Cartes"];
[aCoder encodeInt:a_points forKey:#"Points"];
}
Here is the exception message:
2014-06-04 11:27:34.681 myApp[3693:303] *** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (QCAnnonce)
2014-06-04 11:27:34.794 myApp[3693:303] (
0 CoreFoundation 0x00007fff8937a25c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff8e898e75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8937a10c +[NSException raise:format:] + 204
3 Foundation 0x00007fff8a8acdd9 _decodeObjectBinary + 2349
4 Foundation 0x00007fff8a8ac34d _decodeObject + 288
5 Foundation 0x00007fff8a8d15a5 +[NSKeyedUnarchiver unarchiveObjectWithData:] + 92
6 myApp 0x000000010001365f -[QNProtocolWrap performMethod:withArgumentDatas:onObject:] + 543
7 myApp 0x000000010001261b -[QNConnection methodCall:withArguments:] + 251
8 myApp 0x0000000100012b23 -[QNConnection connectionBaseDidRecieveNewData:] + 211
9 myApp 0x0000000100012b8b -[QNConnection connectionBaseDidRecieveNewData:] + 315
10 myApp 0x000000010000e38c -[QNConnectionBase readInput] + 204
11 myApp 0x000000010000e591 -[QNConnectionBase stream:handleEvent:] + 449
12 CoreFoundation 0x00007fff892ebc81 _signalEventSync + 385
13 CoreFoundation 0x00007fff892ebac8 _cfstream_solo_signalEventSync + 328
14 CoreFoundation 0x00007fff892eb93f _CFStreamSignalEvent + 623
15 CFNetwork 0x00007fff81e4401a _ZN29CoreReadStreamCFStreamSupport19coreStreamReadEventEP16__CoreReadStreamm + 102
16 CFNetwork 0x00007fff81e43f89 _ZN20CoreReadStreamClient25coreStreamEventsAvailableEm + 53
17 CFNetwork 0x00007fff81f77a65 _ZN14CoreStreamBase14_callClientNowEP16CoreStreamClient + 53
18 CFNetwork 0x00007fff81e43ca9 _ZN14CoreStreamBase34_streamSetEventAndScheduleDeliveryEmh + 183
19 CFNetwork 0x00007fff81e43a32 _ZN12SocketStream40dispatchSignalFromSocketCallbackUnlockedEP24SocketStreamSignalHolder + 74
20 CFNetwork 0x00007fff81e43160 _ZN12SocketStream14socketCallbackEP10__CFSocketmPK8__CFDataPKv + 206
21 CFNetwork 0x00007fff81e43062 _ZN12SocketStream22_SocketCallBack_streamEP10__CFSocketmPK8__CFDataPKvPv + 64
22 CoreFoundation 0x00007fff892eb107 __CFSocketPerformV0 + 855
23 CoreFoundation 0x00007fff892ab661 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
24 CoreFoundation 0x00007fff8929cd12 __CFRunLoopDoSources0 + 242
25 CoreFoundation 0x00007fff8929c49f __CFRunLoopRun + 831
26 CoreFoundation 0x00007fff8929bf25 CFRunLoopRunSpecific + 309
27 HIToolbox 0x00007fff89726a0d RunCurrentEventLoopInMode + 226
28 HIToolbox 0x00007fff897267b7 ReceiveNextEventCommon + 479
29 HIToolbox 0x00007fff897265bc _BlockUntilNextEventMatchingListInModeWithFilter + 65
30 AppKit 0x00007fff82a9526e _DPSNextEvent + 1434
31 AppKit 0x00007fff82a948bb -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
32 AppKit 0x00007fff82a889bc -[NSApplication run] + 553
33 AppKit 0x00007fff82a737a3 NSApplicationMain + 940
34 myApp 0x0000000100001262 main + 34
35 myApp 0x0000000100001234 start + 52
36 ??? 0x0000000000000003 0x0 + 3
)
It seems that Class is not loaded to runtime at the moment when you are trying to decode it by NSKeyedArchiver.
If it's not loaded, NSKeyedArchiver just can't find class QCAnnounce. (And that's why it can't decode it)
To check this, you may look in the + (void)load method of NSObject protocol.
The runtime sends this message once per a class right after the Class is loaded into process's address space.
For classes that are part of the program's executable file, the runtime sends the load message very early in the process's lifetime. For classes that are in a shared (dynamically-loaded) library, the runtime sends the load message just after the shared library is loaded into the process's address space.
You can check this by overloading +(void)load method and setting breakpoint there and see if it's have been loaded to runtime before you are calling unarchive.
+ (void)load {
NSLog(#"%# loaded!", self);
}
Your fix [[QCAnnounce alloc] init] works because when Runtime is trying to send first message to a class, it needs to call +(void)initialize to that class and by the time you receive initialize, class in your process should have already received load.
The problem here is that the runtime didn't load all the class present in my static library. As I had no direct call to that class (only id), it was never loaded.
I fixed it by adding -objC in "other linker flags" in the build settings.
Some informations about why this was a good idea were found in this Technical Q&A:
-objC causes the linker to load every object file in the library that defines an Objective-C class or category
There exists two others flags (same Q&A):
-all_load forces the linker to load all object files from every archive it sees, even those without Objective-C code. -force_load is available in Xcode 3.2 and later. It allows finer grain control of archive loading. Each -force_load option must be followed by a path to an archive, and every object file in that archive will be loaded.

Possible reason for crash?

I am using a mapview and sporadically get crashes in iOS7 (both simulator + device). It looks like this:
Exception Type:
EXC_BAD_ACCESS (SIGBUS) Exception Codes:
KERN_PROTECTION_FAILURE at 0x000000000000000c
Application Specific Information: objc_msgSend() selector name: points
iPhone Simulator 463.9.4, iPhone OS 7.0 (iPhone Retina
(3.5-inch)/11A465)
Thread 23 Crashed: 0 libobjc.A.dylib 0x03ea10b2 objc_msgSend + 14
1 MapKit 0x02bd9f0d -[MKPolylineView drawMapRect:zoomScale:inContext:] + 54
2 MapKit 0x02bd98ff __43-[MKOverlayView overlay:drawKey:inContext:]_block_invoke + 847
3 MapKit 0x02bd9572 -[MKOverlayView overlay:drawKey:inContext:] + 268
4 VectorKit 0x0c54741d -[VKRasterOverlay drawKey:inContext:] + 61
5 VectorKit 0x0c5455e5 __40-[VKRasterOverlayTileSource _queueDraw:]_block_invoke + 485
6 libdispatch.dylib 0x04ccd818 _dispatch_call_block_and_release + 15
7 libdispatch.dylib 0x04ce24b0 _dispatch_client_callout + 14
8 libdispatch.dylib 0x04cd0ef1 _dispatch_root_queue_drain + 287
9 libdispatch.dylib 0x04cd113d _dispatch_worker_thread2 + 39
10 libsystem_c.dylib 0x04ffae72 _pthread_wqthread + 441
11 libsystem_c.dylib 0x04fe2d2a start_wqthread + 30
As you can see none of my "own" code is executed. Do you have any guesses on how to proceed finding the root of this problem?
From your error's stack, I look at MKPolylineView documentation . It says that this class is deprecated in iOS 7, use MKPolylineRenderer instead...
Not your code ?
Ok, I go up a little in the stack, same thing for MKOverlayView :
In iOS 7 and later, use the MKOverlayRenderer class to display
overlays instead.
It seems MapKit went into some changes !
Are you doing this on the main thread? If not, try this:
dispatch_async(dispatch_get_main_queue(), ^{
// here goes your UI-operation on your mapview
});

Xcode exception interpretation

Can anyone tell me how to tackle this exception? The debugger is at an exception breakpoint and as you can see there seems to be zero actionable information about the exception. Where did it occur? Pretty sure it's not in my code but I'm at a loss about how to proceed...
Many thanks for any help.
Edit 1:
Here's the console contents
* Terminating app due to uncaught exception 'NSRangeException', reason: '*
-[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack: (0x30ce188f 0x3627e259 0x30c2a9db 0x8d029 0x915c5 0x35723c59 0x35725ee7 0x30cb42ad 0x30c374a5 0x30c3736d 0x36ffb439 0x32917cd5 0x72e4d 0x72de8)
terminate called throwing an exception
Edit 2:
Here's the backtrace
thread #1: tid = 0x1c03, 0x3627e238 libobjc.A.dylib`objc_exception_throw, stop reason = breakpoint 1.1
frame #0: 0x3627e238 libobjc.A.dylib`objc_exception_throw
frame #1: 0x30c2a9da CoreFoundation`-[__NSArrayM objectAtIndex:] + 270
Edit 3 (the solution):
Here's the backtrace using the main() approach
2012-08-31 10:27:21.489 <>[820:707] Uncaught exception *** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array
2012-08-31 10:27:32.908 <>[820:707] Stack trace: (
0 CoreFoundation 0x30ce18a7 __exceptionPreprocess + 186
1 libobjc.A.dylib 0x3627e259 objc_exception_throw + 32
2 CoreFoundation 0x30c2a9db -[__NSArrayM objectAtIndex:] + 270
3 <> 0x00050ed1 __55-[SFSummaryCard retrieveAndDisplayFirstImageForString:]_block_invoke_0 + 148
4 <> 0x0005546d __block_global_1 + 40
5 libdispatch.dylib 0x35723c59 _dispatch_call_block_and_release + 12
6 libdispatch.dylib 0x35725ee7 _dispatch_main_queue_callback_4CF$VARIANT$mp + 194
7 CoreFoundation 0x30cb42ad __CFRunLoopRun + 1268
8 CoreFoundation 0x30c374a5 CFRunLoopRunSpecific + 300
9 CoreFoundation 0x30c3736d CFRunLoopRunInMode + 104
10 GraphicsServices 0x36ffb439 GSEventRunModal + 136
11 UIKit 0x32917cd5 UIApplicationMain + 1080
12 <> 0x00036c01 main + 220
13 <> 0x00036b20 start + 40
)
The key element being: retrieveAndDisplayFirstImageForString()
There is a problem on Xcode 4/iOS 5 that sometimes you don't get the exception traceback in the emulator, due to an apparent bug in the emulator's pseudo OS. The solution is to add an explicit traceback in your main, along the lines of
#try {
retVal = UIApplicationMain...
}
#catch (NSException* exception) {
NSLog(#"Uncaught exception %#", exception);
NSLog(#"Stack trace: %#", [exception callStackSymbols]);
}
You can make exception breakpoint print backtrace in console.
Example:
-(void)backtraceTest
{
NSArray *array = [NSArray arrayWithObjects:#"1", #"2", nil];
id obj = [array objectAtIndex:3]; // out of bounds
NSLog(#"%#", obj);
}
gives this backtrace:
You can see that at line 34 of HelloWorldLayer.m file objectAtIndex method of NSArray was called and then exception happened.
This is relevant:
http://ijoshsmith.com/2011/11/28/debugging-exceptions-in-xcode-4-2/
You can add an "exception breakpoint" that shows backtraces; event handier, you can move it to a "user breakpoint" that appears in all your projects.
Wish I had learned this trick earlier.
I was able to resolve by workaround:
Closed all open applications
relaunch Finder
run sudo find / -name ".DS_Store" -exec rm {} \;
this removes all .DS_Store old files on the computer
launch finder and set default view to "LIST VIEW" as shown here: http://macs.about.com/od/usingyourmac/ss/Setting-Finder-Views-For-Folders-And-Su b-Folders_2.htm
rerun the offending application and file chooser works