Load objective-c library in R with RCocoa - objective-c

I found the R package Cocoa at http://www.rforge.net/Cocoa/, and I want to use it call my customized objective-c classes.
I've tried to load a dylib which contains a simple custom class (called DOHello as below) and then call:
hc <- .MClass("DOHello")
h <- .M(hc, "alloc")
h <- .M(h, "init")
.M(h, "hello")
The first three line of code is ok, but when I call .M(h, "hello"), the whole RStudio session crashes. I also tried to add the source code of DOHello to the Cocoa package directly, the result is same.
The class DOHello:
#interface DOHello : NSObject
- (void)hello;
#end
#implementation DOHello
- (void)hello {
printf("Hey, there");
}
#end
The crash report:
Process: rsession [8215]
Path: /Applications/RStudio.app/Contents/MacOS/rsession
Identifier: rsession
Version: ???
Code Type: X86-64 (Native)
Parent Process: RStudio [1931]
User ID: 502
Date/Time: 2013-03-04 11:47:44.858 +0800
OS Version: Mac OS X 10.8.2 (12C54)
Report Version: 10
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 com.apple.CoreFoundation 0x00007fff867d301d __NSI0 + 621
1 com.apple.CoreFoundation 0x00007fff867d2aee -[NSInvocation getArgument:atIndex:] + 302
2 Cocoa.so 0x000000010c4fef4f ObjCsendMsg + 1135
3 libR.dylib 0x0000000109ffee37 do_External + 327 (dotcode.c:540)
4 libR.dylib 0x000000010a02e448 Rf_eval + 1672 (eval.c:494)
5 libR.dylib 0x000000010a02fedd do_begin + 141 (eval.c:1415)
6 libR.dylib 0x000000010a02e29c Rf_eval + 1244 (eval.c:468)
7 libR.dylib 0x000000010a0333b1 Rf_applyClosure + 849 (eval.c:861)
8 libR.dylib 0x000000010a02e1b2 Rf_eval + 1010 (eval.c:512)
9 libR.dylib 0x000000010a0669e2 Rf_ReplIteration + 514 (main.c:256)
10 libR.dylib 0x000000010a066cd1 R_ReplConsole + 161 (main.c:306)
11 libR.dylib 0x000000010a0671ea run_Rmainloop + 90 (main.c:988)
12 rsession 0x0000000109786b1b r::session::runEmbeddedR(core::FilePath const&, core::FilePath const&, bool, bool, SA_TYPE, r::session::Callbacks const&, r::session::InternalCallbacks*) + 427
13 rsession 0x0000000109769b29 r::session::run(r::session::ROptions const&, r::session::RCallbacks const&) + 3193
14 rsession 0x0000000109386f35 main + 14517
15 rsession 0x000000010936e154 start + 52
The crash report is not complete, I just copied the section which I think is useful.

This was a bug in Cocoa where it was trying to retrieve the result from a void method - now fixed. Please use stats-rosuda-devel mailing list or e-mail the author for questions and bug reports.

Related

SIGABRT/Unrecognized Selector

My app is essentially a collection of cards, each with various messages/information on it. One swipes to go through these cards, generally swiping right. I am currently getting this sig abrt error:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
It also prints, this:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[filterPageViewController askForPushNotifications]: unrecognized selector sent to instance 0x7f8b6d0acd80'
*** First throw call stack:
(
0 CoreFoundation 0x000000010fa92d85 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010f506deb objc_exception_throw + 48
2 CoreFoundation 0x000000010fa9bd3d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010f9e1cfa ___forwarding___ + 970
4 CoreFoundation 0x000000010f9e18a8 _CF_forwarding_prep_0 + 120
5 Lettuce 0x000000010a2780a6 -[DraggableViewBackground cardSwipedRight:] + 2470
6 Lettuce 0x000000010a2d0ad5 -[DraggableView rightAction] + 453
7 Lettuce 0x000000010a2d02ed -[DraggableView afterSwipeAction] + 77
8 Lettuce 0x000000010a2cfe22 -[DraggableView beingDragged:] + 1922
9 UIKit 0x000000010d9c7b28 _UIGestureRecognizerSendTargetActions + 153
10 UIKit 0x000000010d9c419a _UIGestureRecognizerSendActions + 162
11 UIKit 0x000000010d9c2197 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 843
12 UIKit 0x000000010d9ca655 ___UIGestureRecognizerUpdate_block_invoke898 + 79
13 UIKit 0x000000010d9ca4f3 _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 342
14 UIKit 0x000000010d9b7e75 _UIGestureRecognizerUpdate + 2634
15 UIKit 0x000000010d54448e -[UIWindow _sendGesturesForEvent:] + 1137
16 UIKit 0x000000010d5456c4 -[UIWindow sendEvent:] + 849
17 UIKit 0x000000010d4f0dc6 -[UIApplication sendEvent:] + 263
18 UIKit 0x000000010d4ca553 _UIApplicationHandleEventQueue + 6660
19 CoreFoundation 0x000000010f9b8301 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
20 CoreFoundation 0x000000010f9ae22c __CFRunLoopDoSources0 + 556
21 CoreFoundation 0x000000010f9ad6e3 __CFRunLoopRun + 867
22 CoreFoundation 0x000000010f9ad0f8 CFRunLoopRunSpecific + 488
23 GraphicsServices 0x00000001107e2ad2 GSEventRunModal + 161
24 UIKit 0x000000010d4cff09 UIApplicationMain + 171
25 Lettuce 0x000000010a2c3f0f main + 111
26 libdyld.dylib 0x000000011012492d start + 1
27 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
After some investigating, I have found the problematic code. It is a line within my cardSwipedRight method that is in my draggableviewbackground class (this class functions as a deck, to hold all of the cards) :
[((settingsTableViewController *)([obj.superNavController.viewControllers[obj.profileNum] viewControllers][0])) askForPushNotifications];
This line of code is within an if statement that checks whether this is a "sign me up for notifications card". What I'm confused by, is why xcode associated filterPageView with askForPushNotifications. Not only does filterPageView not have a askForPushNotifications method, but I don't swipe right on filterPageView nor have I viewed it by the time my app crashes.
One receives an unrecognized selector exception when the object to which the selector is sent does not implement/respond to the sent selector. In simple words, if a class A does not implement a method and someone try to call that method on an object of class A, runtime throws an unrecognized selector exception.
When we are not sure whether an object will respond to a selector, we should have a safety check to see if an object responds to intended selector.
For eg.
if ([*obj* respondsToSelector:#selector(*selector*)])
{
[*obj* performSelector:*selector*];
}
unrecognized selector sent to instance comes up when you try to call a method on an object but that method doesn't exist (The corrrect terminology is that you have tried to send a message called "askForPushNotifications" but the settingsTableViewController does not understand it as it(askForPushNotifications) doesn't exit . I am sure you may not have that method in your settingsTableViewController. Please check and let me know if that helped you.
Also, please check with respondsToSelector if the object actually responds to the method askForPushNotifications. It may be the case that
((settingsTableViewController
*)([obj.superNavController.viewControllers[obj.profileNum] viewControllers][0]))
may not be of type SettingsTableViewController. Please check
if [(((settingsTableViewController *)([obj.superNavController.viewControllers[obj.profileNum] viewControllers][0])) respondsToSelector:#selector(askForPushNotifications)]
{
[((settingsTableViewController *)([obj.superNavController.viewControllers[obj.profileNum] viewControllers][0])) askForPushNotifications];
}

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
});

CallCenter crashes the app

I have a huge issue with the CTCallCenter where the phone crashes if you get a call but never asnwers. Then the music should come back but instead evertyhing just dies.
This is what the code looks like:
_callCenter = [[CTCallCenter alloc] init];
_callCenter.callEventHandler = ^(CTCall* call){
if (call.callState == CTCallStateDialing || call.callState==CTCallStateIncoming) {
_shouldResumeSongIfConnectionIsAlive=NO;
if([[TFAudioPlayer sharedAudioPlayer] status]==TFAudioPlayerStatusPlaying){
[[TFAudioPlayer sharedAudioPlayer] pause];
isAppWasPlaying=YES;
}else isAppWasPlaying=NO;
}else if(call.callState==CTCallStateDisconnected){
if(isAppWasPlaying){
[[TFAudioPlayer sharedAudioPlayer] playForcedFromWhereItStopped];
_shouldResumeSongIfConnectionIsAlive=YES;
}
}
};
I cannot find any way to handle the case where the user doesnt pick up their phone. The CTCallCenter only has Incoming, Disconnect, Connect and Dialing from what I could see.
Does anyone have a clue?
Edit:
This issue only appears when I run the app on the phone when its NOT connected and debugging. The app dies directly when the other person hangs up (missed call).
Stacktrace:
Date/Time: 2012-11-19 14:20:47.470 +0100
OS Version: iPhone OS 5.1 (9B179)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0xbbadbeef
Crashed Thread: 10
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0:
0 libsystem_kernel.dylib 0x356bb004 mach_msg_trap + 20
1 libsystem_kernel.dylib 0x356bb1fa mach_msg + 50
2 CoreFoundation 0x372203ec __CFRunLoopServiceMachPort + 120
3 CoreFoundation 0x3721f0ea __CFRunLoopRun + 818
4 CoreFoundation 0x371a249e CFRunLoopRunSpecific + 294
5 CoreFoundation 0x371a2366 CFRunLoopRunInMode + 98
6 GraphicsServices 0x320af432 GSEventRunModal + 130
7 UIKit 0x33926e76 UIApplicationMain + 1074
8 My App 0x0001e63c 0x1a000 + 17980
9 My App 0x0001c268 0x1a000 + 8808
Also! If I run the app with DEPLOY POSTPROCESSING = YES it doesnt crash. I dont get it

Crash with RestKit when issuing multiple requests in quick succession

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.