0

I have just jumped into Objective-C and I got stuck pretty early on. I will post code with my question but to keep it readable i'll get rid of some of the crap, let me know if you want more code posted!

I have created a new object called 'Phrase' (subclassed from NSObject), and am reading items from JSON into these 'Phrase' objects and adding them to an array. Here's the first lot of code:

Example JSON:

    {
    "phrases": [
        {
            "title": "Title of my Phrase",
         "definition" : "A way to look at some words",
   "location" : "Irish Proverb"
        }   
    ]
    }

Script I'm reading it in with:

    - (void)viewDidLoad {
    [super viewDidLoad];

 self.phraseDictionary = [[NSMutableArray alloc] initWithObjects:nil];

 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"phrase" ofType:@"json"];  
 NSString *myRawJSON = [[NSString alloc] initWithContentsOfFile:filePath];

 NSData *jsonData = [myRawJSON dataUsingEncoding:NSUTF32BigEndianStringEncoding];
 NSDictionary *entries = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:nil];


 for (id key in entries) {

  NSObject *phrases = [entries objectForKey:key];

  for (id phrase in phrases) {

   Phrase *pushArrayToPhrase = [[Phrase alloc] initWithText:[phrase objectForKey:@"title"] definition:[phrase objectForKey:@"definition"] location:[phrase objectForKey:@"location"]];
   [self.phraseDictionary addObject:pushArrayToPhrase];

  }

    }
    }

Phrase m file:

#import "Phrase.h"


@implementation Phrase

@synthesize title;
@synthesize definition;
@synthesize location;

- (id)init {
 self = [super init];
 if (self != nil) {
  title = @"";
  definition = @"";
  location = @"";
 }
 return self;
}

- (id)initWithTitle:(NSString *)tit definition:(NSString *)def location:(NSString *)loc {
 self = [super init];
 if (self != nil) {
  title = tit;
  definition = def;
  location = loc;
 } 
 return self;
}


@end

From here I loop through the objects and add them to a list in my splitview:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

 static NSString *CellIdentifier = @"CellIdentifier";

 // Dequeue or create a cell of the appropriate type.
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    Phrase *cellPhrase = [self.phraseDictionary objectAtIndex:indexPath.row];
 cell.textLabel.text = cellPhrase.title;
 return cell;
}

But when I click an item, and ask for a phrase based on the indexPath.row of the one clicked, I can only ever access the property used in the cell.textLabel.text. Any other attempt from here on in to access a property from the Phrase object exits the simulator.

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

 Phrase *cellPhrase = [self.phraseDictionary objectAtIndex:indexPath.row];
 detailViewController.detailItem = cellPhrase;
 //If i attempt 'cellPhrase.definition' here, the app will close without an error

}

Hope that's easy to follow, let me know if it's not and i'll try again!

jamie-wilson
  • 1,925
  • 21
  • 38
  • Any infos why it exists? Have you checked the logs? – Georg Schölly Sep 09 '10 at 05:50
  • As I just posted below, I got this "Program received signal: “EXC_BAD_ACCESS”." when I turned on debugging. I saw this link http://stackoverflow.com/questions/327082/exc-bad-access-signal-received but couldn't relate it to my situation... – jamie-wilson Sep 09 '10 at 20:39

1 Answers1

1

In the initWithTitle method you are assigning the variables but not retaining them. If they are not retained anywhere they will be released and when you try to access them your app will crash. If you are not getting any error messages make sure you turn debugging on.

skorulis
  • 4,361
  • 6
  • 32
  • 43
  • What do you mean by assigning but not retaining? (I'm new to this, so still getting my head around assign/retain etc) - Where i have title = tit;definition=def etc in the initWithTitle method, do i need to be doing this differently? – jamie-wilson Sep 09 '10 at 20:38
  • Also - I turned on debugging and I get "Program received signal: “EXC_BAD_ACCESS”." – jamie-wilson Sep 09 '10 at 20:38
  • When you do title = tit; there is nothing stopping the memory reserved by the string from being released later on. So next time you try to access the string your program will crash as the memory isn't valid anymore. To prevent this try title = [tit retain]; or if your properties are retain you can do self.title = tit; Then in your dealloc method do [title release]; to make sure the memory is cleaned up later on. – skorulis Sep 09 '10 at 23:16
  • Thanks heaps, that did the trick. Do you have any suggestions for good reading regarding memory management / retaining etc in objective-c or even around the general principles? – jamie-wilson Sep 10 '10 at 01:43