1
void CountlyRecordEventSegmentationCountSum(const char * key, const char * segmentation, int count, double sum)
{
    NSString * seg = CreateNSString(segmentation);
    NSArray * entries = [seg componentsSeparatedByString:@"`"];
    NSDictionary * dict = [NSDictionary dictionary];
    for (id entry in entries)
    {
        NSArray * keyValue = [entry componentsSeparatedByString:@"|"];
        [dict setValue:[keyValue objectAtIndex:1] forKey:[keyValue objectAtIndex:0]];
    }
    [[Countly sharedInstance] recordEvent:CreateNSString(key) segmentation:dict count:count sum:sum];
}

I put "?" in the title because I'm not entirely sure if the problem is in the code above but that's my best guess. I'm integrating Countly iOS plugin with Unity and one of Countly plugin's methods take NSDictionary * as argument. As I don't know how to send a dictionary from C# to Objective-C I'm storing my dict in a string, sending it to Objective-C and then recreating the dictionary (the code above).

But that's probably even not relevant. I know EXC_BAD_ACCESS usually has something to do with unfreed resources or sth so maybe you can see what I'm doing wrong (I don't know Objective-C at all, just writing a few lines needed by the plugin).

Edit: From Unity sample:

// Converts C style string to NSString
NSString * CreateNSString (const char * string)
{
    if (string)
        return [NSString stringWithUTF8String: string];
    else
        return [NSString stringWithUTF8String: ""];
}
NPS
  • 6,003
  • 11
  • 53
  • 90
  • Did you try with an NSMutableDictionnary instead of the traditional NSDictionnary? – Alexis C. May 15 '13 at 08:59
  • @Kirualex it is not "traditional", it is immutable. One cannot modify contents of the NSDictionary after it's initialization. One should use NSMutableDictionary instead – art-divin May 15 '13 at 09:02
  • Check whether keyValue Array always contains 2 objects. B'coz you are using objectAtIndex:1 and objectAtIndex:0. So, not sure does it contains 2 objects. Check with a condition. – Manu May 15 '13 at 09:03
  • @art-divin Can I use `NSMutableDictionary *` as an argument for a function that takes `NSDictionary *` as an argument? – NPS May 15 '13 at 09:05
  • You can use NSMutableDictionary where ever you would use an NSDictionary normally. It is a subclass of NSDictionary. But it is mutable. Meaning, your code woud crash on sending "setValue:" to the dictionary object anyway. But that is not (yet) your problem because that would throw a different exception. – Hermann Klecker May 15 '13 at 09:14
  • For your abort - did you set an All-Exceptions breakpoint? Doing so you will have a chance to fingerpoint on the line that causes the exception. If not, then it may get nasty. – Hermann Klecker May 15 '13 at 09:16
  • Apparently that **was** the problem because after changing to `NSMutableDictionary *` the application doesn't crash or throw any exceptions anymore. art-divin, make your comment an answer and get accepted. ;) – NPS May 15 '13 at 09:17
  • Anyway, the call stack could give a hint on where the exception was thrown. Did you look at it? Click on every method of your own within the call stack and see what object is dealt with then the error occurs. – Hermann Klecker May 15 '13 at 09:17

2 Answers2

2

You need to be using NSMutableDictionary, you can't modify an NSDictionary.

Also, you should use setObject:forKey: because setValue:forKey: is a KVC method. It happens to do the same thing on an NSMutableDictionary for most keys, but it is marginally slower.

Finally, you should check that [keyValue count] >= 2 before trying to access the objects at indexes 0 and 1.

Edit Also, CreateNSString() looks suspicious. It might be either leaking or prematurely releasing the string. But you need to post the code. In any case, I'd use

 seg = [NSString stringWithUTF8String: segment];

or, other appropriate method if segment is not encoded in UTF-8.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • `CreateNSString()` is from Unity sample, posted the code in edit to my question. – NPS May 15 '13 at 12:51
2

The error you've made is that you are trying to modify immutable version of NSDictionary.

One cannot modify contents of the NSDictionary after it's initialization. You should use NSMutableDictionary instead.

Here is a documentation on NSMutableDictionary. And here is an example of how to create mutable version of an immutable object that conforms to NSMutableCopying protocol.

Community
  • 1
  • 1
art-divin
  • 1,635
  • 1
  • 20
  • 28