0

In one of my methods, I fetched and parsed a JSON and placed it inside an NSArray called jsonArray in -(void)method1. I then copied the contents of that jsonArray to an NSMutableArray called copiedJsonArray to be used on other methods. Problem is, copiedJsonArray crashes whenever I log its contents in the console from the other methods -(void)method2 but it logs fine in -(void)method1.

How can I fix this?

In my header file:

@interface MainViewController : UIViewController

@property (nonatomic, retain) NSMutableArray *copiedJsonArray;

In my implementation file:

@synthesize copiedJsonArray;

- (void)viewDidLoad
{
    [self method1];
}

- (void)method1
{
    NSString *urlString = [NSString stringWithFormat:THE_URL]; 
    NSURL *url = [NSURL URLWithString:urlString];
    NSData *data = [NSData dataWithContentsOfURL:url];
    NSString *jsonString = [[[NSString alloc] initWithData:data
                                              encoding:NSUTF8StringEncoding] autorelease];
    NSDictionary *jsonDictonary = [jsonString JSONValue];
    NSArray *jsonArray = [jsonDictonary valueForKeyPath:@"QUERY.DATA"];

    self.copiedJsonArray = [[NSMutableArray alloc] initWithArray:jsonArray copyItems:YES];

    NSLog(@"Copied JSON Array in Method 1: %@", self.copiedJsonArray);

    [self method2];
}

- (void)method2
{
    NSLog(@"Copied JSON Array in Method 2: %@", self.copiedJsonArray);
}

I also tried doing this too but it does the same error:

copiedJsonArray = [jsonArray mutableCopy];

I also tried implementing NSCopy but fails too:

@interface MainViewController : UIViewController <NSCopying>
{
    NSMutableArray *copiedJsonArray;
}

I'm doing this so that I can do a loop in my copiedJsonArray without fetching its contents from JSON again and again when the user taps on my UISegmentedControl.

halfer
  • 19,824
  • 17
  • 99
  • 186
jaytrixz
  • 4,059
  • 7
  • 38
  • 57
  • [Are you using ARC or not?](http://stackoverflow.com/questions/10508228/how-to-know-if-my-xcode-iphone-project-is-using-arc) Also, post your real code; the above `method1` won't work because `jsonDictonary` (sic) hasn't been declared. – Kurt Revis Jan 13 '13 at 07:00
  • I'm not using ARC. Will edit my post with the code for jsonDictionary if that helps. – jaytrixz Jan 13 '13 at 07:07
  • Post the full console error msg. Am not psychic! – occulus Jan 13 '13 at 12:14
  • 0x18b709f: movl (%edi), %esi - Thread 1: EXC_BAD_ACCESS (code=2, address=0x0) while I only have copiedJsonArray: (null) and (lldb) on my console. That (null) is my log that checks if the array has values. – jaytrixz Jan 13 '13 at 15:50

1 Answers1

0

If you call method2 before method1 it will crash as copiedJasonArray has not been created. You should not create instance variables inside methods (as you cannot know if they have been called). You should do it when you create your viewController, in viewDidLoad for example.

And use properties:

@interface
@property (retain) NSMutableArray* copiedJsonArray;
@end

then either

@synthesize copiedJsonArray = _copiedJsonArray

or leave that line it out (the compiler will put it in automatically in 4.5)

access as self.copiedJsonArray or _copiedJSONArray.
Outside of getters,setters,inits and deallocs, use the self. form, it's safer.

You could also create _copiedJsonArray lazily in the setter:

- (NSMutableArray*) copiedJsonArray
{
   if (!_copiedJasonArray)
         _copiedJsonArray = [NSMutableArray alloc] init;
   return _copiedJasonArray;
}
Community
  • 1
  • 1
foundry
  • 31,615
  • 9
  • 90
  • 125
  • I already did that yet still, same error happens. @property (retain) NSMutableArray *copiedJsonArray; and synthesized it and accessed it via self.copiedJsonArray. I just placed the name -(void)method1 as an example but they're not the real method names I use. Also, m-(void)emthod1 is first called. – jaytrixz Jan 13 '13 at 15:51
  • where are you creating your array now? – foundry Jan 13 '13 at 15:54
  • Can you NSLog it as soon as it is created? Then NSLog it again from multiple points in your program to find whether it ONLY crashes in method2, or in other places as well. Does it ONLY crash after method1 has run, and not before, for example? Get more info... What crash info do you get in the log? – foundry Jan 13 '13 at 15:56
  • See my edited post above. The log I get from method1 doesn't return null while the log I get from method2 returns null and thus the crash. – jaytrixz Jan 13 '13 at 16:48
  • 1
    Your code - as it is - seems fine. But for clarity can you differentiate between your iVar and your property name, as per my answer, and _always_ address the iVar via it's property, i.e. `self.copiedJSONArray`. Just to be really sure you are accessing the iVar in both cases. Also move your alloc/init method into your viewDidLoad to be sure you only ever call it once. Then log it after you have created it in viewDidLoad, log it again at the start and end of method1... None of this will fix your error, but it might make finding the problem easier. – foundry Jan 13 '13 at 17:13
  • Then step through in the debugger. If the contents of copiedJSONArray are changing you should see where it happens. – foundry Jan 13 '13 at 17:14
  • I just forgot to add `self.copiedJsonArray` in my edit. Apologies. I'll edit my post above and do your suggestions. Thanks. I'll comment again if it fails. – jaytrixz Jan 13 '13 at 17:24
  • Error again and now it starts on method1. The breakpoint points here: `[self.copiedJsonArray initWithArray:jsonArray copyItems:YES];` I tried `self.copiedJsonArray = [jsonArray mutableCopy];` and there's no error on method1 but it still ends up with the same error message from before on my method2 log. I tried doing what you said and `self.copiedJsonArray` only contains values after method1 ends. At the start of both method1 and method2, it returns (null). This is getting frustrating already. – jaytrixz Jan 13 '13 at 17:39
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/22674/discussion-between-he-was-and-jaytrixz) – foundry Jan 13 '13 at 17:54