0

The error is a EXC_BAD_ACCESS, which is typically a bad pointer of some sort, but the problematic _rawText property is created in the same scope where it fails. Here's the code from the command line tool. The only difference between this and the app version is the URL for the file, and via NSLog I've verified that both files are being read and have the same length, as they should.

Here's the updated code, which sometimes runs and sometimes fails. I'm using getters and setters for rawText this time around, instead of accessing _rawText directly.

-(void)loadDictionary {
  NSURL *cedict_url = [NSURL fileURLWithPath:@"cedict_ts.txt"];
  NSLog(@"cedict_url is %@", cedict_url);
  NSError *loadError;
  [self setRawText:[NSString stringWithContentsOfURL:cedict_url encoding:NSUTF8StringEncoding error:&loadError]];
  // _rawText = [NSString stringWithContentsOfURL:cedict_url encoding:NSUTF8StringEncoding error:&loadError];
  if (_rawText == nil) NSLog(@"No _rawText object");
  if (loadError == nil) NSLog(@"No error from stringWithContentsOfURL:");
  if (loadError) {
      NSLog(@"%@", loadError);
      return;
  } else {
      // This next line fails with the error "Thread 1: EXC_BAD_ACCESS (code=1, address=0x20)
      NSLog(@"Dictionary loaded, string of length %lu", (unsigned long)[[self rawText] length]);
      // 0x20 is kind of small for an NSString's memory location
  }
  NSArray *rawLines = [[self rawText] componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
  NSLog(@"Broke file into %lu lines", (unsigned long)[rawLines count]);
  NSLog(@"First 10 lines are...");
  for (int iLine = 0; iLine < 10; iLine++) {
      NSString *theLine = [rawLines objectAtIndex:iLine];
      NSLog(@"Line %d, %lu characters: %@", iLine, theLine.length, theLine);
  }
  NSMutableArray *singleHanCharacterLines = [NSMutableArray arrayWithCapacity:[rawLines count]];
  for (NSInteger i=0; i<[rawLines count]; i++) {
      NSString *line = [rawLines objectAtIndex:i];
      NSComparisonResult hasHash = [line compare:@"#" options:NSCaseInsensitiveSearch range:NSMakeRange(0, 1)];
      NSComparisonResult isSpace = [line compare:@" " options:NSCaseInsensitiveSearch range:NSMakeRange(1, 1)];
      BOOL nonComment = hasHash != NSOrderedSame;
      BOOL oneHanLine = isSpace == NSOrderedSame;
      if (nonComment & oneHanLine) [singleHanCharacterLines addObject:line];
    }
    NSLog(@"Found %lu lines starting with a single Han character", (long int)[singleHanCharacterLines count]);
    dLines = [NSArray arrayWithArray:singleHanCharacterLines];
  }

The NSLog that prints the length of _rawText gives the same result for both versions.

Are there some settings that I need to change, or some additional techniques I've forgotten? Thanks!

Scamp Dog
  • 68
  • 1
  • 8
  • 3
    Don't know if this has to do with the crash, but: never test whether your `NSError` pointer is `nil` to determine if a method has failed. You must always test the direct return value to determine if it has failed and examine the `NSError` only if it has. Beyond that, show which line the crash is occurring on and the full details of the crash. For example, for an EXC_BAD_ACCESS, what address was it trying to access? – Ken Thomases Jul 18 '16 at 18:32
  • I just added a check that loadError is nil, and now it runs. Huh. – Scamp Dog Jul 18 '16 at 18:39
  • 2
    Don't check `loadError`, check `_rawText`. Or is that what you meant? – Ken Thomases Jul 18 '16 at 18:40
  • Edit: I just realized I misunderstood your comment, that I shouldn't be checking loadError. A check that _rawText isn't nil passed as well. So I was checking loadError two different ways... I am stumped. – Scamp Dog Jul 18 '16 at 18:51
  • 1
    Perhaps edit the question to show the improved code. Also, don't forget my second request to show which line had the error and the full details. – Ken Thomases Jul 18 '16 at 19:31

0 Answers0