访问实例变量时出现EXC_BAD_ACCESS内存问题

时间:2011-12-09 06:57:32

标签: objective-c

我在移植我刚刚使用过的Objective-C代码的Java项目时遇到了问题 - 我在这段代码的第一行收到“程序接收信号:”EXC_BAD_ACCESS“”:

-(Point3D *) unit {
  NSLog(@"%@%@", "X: ", x);
  double length = [self length];
  return [[Point3D alloc] initWithX:x/length andY:y/length andZ:z/length];
}

从这里打电话:

-(id) initWithStart:(Point3D *)start andDirection:(Point3D *)dir {

  if ( self = [super init] ) {

    NSLog(@"%@%@", @"Direction:", [dir toString]);

    printf("Trying to find unit length of direction...\n");
    NSLog(@"%@", [[dir unit] toString]);


    self.start = start;
    self.direction = [dir unit];
  }

  return self;
}

控制台输出为:

2011-12-09 17:20:14.021 RayTracerProject[16607:407] Direction:(0,0,20)
Trying to find unit length of direction...

Point3D的toString方法如下所示:

-(NSString *) toString {
  NSNumber *xstring = [NSNumber numberWithDouble:self.x];
  NSNumber *ystring = [NSNumber numberWithDouble:self.y];
  NSNumber *zstring = [NSNumber numberWithDouble:self.z];

  NSString * str = @"(";
  str = [str stringByAppendingString:[xstring stringValue]];
  str = [str stringByAppendingString:@","];
  str = [str stringByAppendingString:[ystring stringValue]];
  str = [str stringByAppendingString:@","];
  str = [str stringByAppendingString:[zstring stringValue]];
  str = [str stringByAppendingString:@")"];

  return str;
}

所以,从我所看到的情况来看,当我使用(Point3D *) dir调用检查值是多少时,我的[dir toString]还活着。但是当我尝试调用[dir unit]时,似乎我不再拥有我在对象中所做的变量,因此EXC_BAD_ACCESS错误。

我在这里做错了什么?我认为这与我管理(或不管理)内存使用的方式有关,但我不知道它是什么。

2 个答案:

答案 0 :(得分:2)

方法'unit'中的NSLog应为:

NSLog(@"%@ %g", @"X:", x);

移动空间是可选的,但只是让它更清晰。关键问题是您在@之前错过了"X: ",并且您需要使用%g而不是%@,因为从您的其他代码x是双倍而不是NSLog(@"X: %g", x); 一个NSObject。等效 - 但更简单,因此更好 - 也将是:

%@

Apple的文档提供了definitive guide to string format specifiers,并且周围的文档解释了使用格式说明符,如%g(用于引用Objective C对象)和{{1}}(用于引用64-构造NSString时的位浮点数。

答案 1 :(得分:0)

这一行似乎在这里:

NSLog(@"%@%@", "X: ", x);

看起来应该更像这样:

NSLog(@"%@%lf", @"X: ", self.x);

请注意这里的一些变化:

  • 从您的其他代码中,您似乎有一个名为“x”的属性。 self.x引用该属性。 (您可能也可能没有名为'x'的实例变量)
  • 同样来自您的其他代码,您的属性“x”似乎是双倍的。因此,double的占位符为%lf,而不是%@%@适用于NSObjects(和后代)
  • NSString文字以@开头。所以@"X: "是一个NSString文字。你拥有的是一个C字符串。

修改

好吧,我像往常一样慢。 :)忽略我所说的并接受Duncan的答案,实际上这个答案更快,更清洁。