【问题标题】:getting EXC_BAD_ACCESS_CODE, objective C获取 EXC_BAD_ACCESS_CODE,目标 C
【发布时间】:2012-05-17 05:23:32
【问题描述】:

我正在做的是

//ClassB.h @property (strong, nonatomic) NSString *name;

//ClassA.h @interface ClassA:NSObject +(ClassA*)methodA:(NSData*)data; -(id)initWithData:(NSData*) 数据; @property (nonatomic, strong) NSMutableArray *arr; @property (nonatomic, strong) RXMLElement *rxmlRoot; @结尾 //ClassA.m @实现类A @synthesize arr; @synthesize rxmlRoot; +(ClassA*)methodA:(NSData*)data { 返回 [[ClassA alloc] initWithData:data]; } -(id)initWithData:(NSData*)data { self = [超级初始化]; 如果(自我){ arr = [NSMutableArray 数组]; rxmlRoot = [RXMLElement elementFromXMLData:data]; /*****edit : 刚刚添加以使代码清晰*****/ NSString *node = @"players.player"; [rxmlRoot 迭代:节点与:^(RXMLElement *e){ ClassB *classB = [[[ClassB alloc] init] autorelease]; [classB setName:[e属性:@“name”]]; // 将 ClassB 添加到 arr [arr addObject:classB]; }]; } 回归自我; } @结尾

所以现在我有 ClassA 对象,其 arr 包含 ClassB

问题:稍后,当我尝试访问 ClassB 的特定属性时,例如

((ClassB*)[classA.arr objectAtIndex:0]).name

我在上面一行得到 EXC_BAD_ACCESS..

请就这个问题以及如何纠正错误给我建议。这里欢迎任何cmets

谢谢

【问题讨论】:

    标签: iphone exc-bad-access


    【解决方案1】:

    这一行

    [arr addObject:ClassB]
    

    没有意义。您打算将 ClassB 的 instance 放入该数组还是该类本身(即[ClassB class])?大概您必须打算在其中放置一个 ClassB 的实例,否则稍后尝试访问其属性(例如firstName)将毫无意义。另外,您的 ClassB 是否甚至具有 firstName 属性,因为您向我们展示的 ClassB 界面仅提到了 name 属性。

    更新:

    由于您使用手动内存管理,您需要保留您在初始化程序中使用便利构造函数创建的对象(arr、rxmlRoot),这些构造函数返回自动释放的对象。例如,代码应该是

    arr = [[NSMutableArray array] retain];
    

    【讨论】:

    • 那么您实际上在 ClassB 中是否有 firstName 属性?
    • 对此我感到非常抱歉。 firstName 应该是名字。
    • 我正在使用手动...
    • 或者不要像 UIAdam 建议的那样自己保留它,而是使用您创建的属性。 (为了清楚起见,我将“强”更改为“保留”——当 ARC 关闭时,它们会做同样的事情——但“强”与 ARC 代码相关联,因此可能会造成混淆)。所以 [self setArr: [NSMutableArray array]];然后你合成的setter为你做内存管理。但重点是好的。出现 EXC_BAD_ACCESS 是因为您正在向已释放的对象发送内容。
    • @MatthewElton 虽然你说得对,它会起作用,但我相信流行的惯例是避免在初始化程序中使用属性,以防它们具有对未完全初始化的对象无效的副作用。
    【解决方案2】:

    问题中的代码已经发生了很大的变化,所以我之前的答案现在没有意义,我已经将其删除了。给定修改后的代码,首先要做的是记录发生了什么。

    NSLog(@"classA: %@", classA);
    NSLog(@"classA.arr: %@", classA.arr);
    
    ((ClassB*)[classA.arr objectAtIndex:0]).name
    

    如果它在第一个日志语句中爆炸,那么情况就很糟糕了。但至少你知道 classA 指向的东西已经烂了,你可以从那里开始工作。

    您可以在调试器中实现相同的目的,方法是在行前设置断点并进行检查。鉴于您得到一个 EXC_BAD_ACCESS 指针之一指向一个狡猾的对象,例如一个已经发布的。看起来你正在使用 ARC(因为你的属性很强大),这应该有助于管理内存 - 但话说回来,你有一个自动释放,所以可能没有。

    【讨论】:

    • 如果您在第一次提出问题时发布实际编译的代码,其他 stackoverflow 用户会很感激。否则,人们会发现错误的问题。当然,发布非常短的代码也很好,这就是为什么如果您提取尽可能多的代码但仍然存在问题,然后才发布您的问题和代码,人们会欣赏它的原因。 (经验表明,当你这样做时,大约 50% 的时间,你在需要在这里发布之前解决了问题。)
    【解决方案3】:

    发布您的 ClassB.m 。 您是否正在制作@synthesize 名称?

    同时为 arr 进行 Alloc。

    这行错了:

    ((ClassB*)[classA.arr objectAtIndex:0]).firstName
    

    您的字符串称为 name ,而不是 firstName。应该是:

    ((ClassB*)[classA.arr objectAtIndex:0]).name
    

    【讨论】:

    • 我刚刚编辑过。 firstName 毕竟应该是名字。对于那个很抱歉。我确实使用 arr = [NSMutableArray array]; 创建了一个 arr
    • 尝试进行分配。像
    • arr = [[NSMutablearray alloc] initWithCapacity:0];
    猜你喜欢
    • 2012-11-24
    • 1970-01-01
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多