我正在尝试使用这段代码在我的应用中切换视图:
self->variable1 = [[NSNumber alloc] initWithInt:0];
self->variable2 = [[NSMutableArray arrayWithCapacity:1];
self->variable3 = [[NSMutableArray arrayWithCapacity:1];
[self presentModalViewController:titleScreen animated:YES];
如果我注释掉所有分配的变量行,代码工作正常。如果代码中只有1行崩溃,则出现“EXC_BAD_ACCESS”错误。为什么会这样?变量根本没有被使用,只是声明供以后使用。我也没有得到任何编译错误。我做错了什么?
更新
谢谢大家的帮助。我改变了将我的变量声明为@ property / @ synth以清理我的代码的方式,但它没有解决问题。经过长时间的摆弄,我修好了。我改变了代码:
self.variable1 = [[NSNumber alloc] initWithInt:0];
到此:
self.variable1 = [NSNumber alloc];
[self.variable1 initWithInt:0];
它有效!有人可以解释为什么这有效,第一行没有?
更新
谢谢Peter Hosey向我展示了我的邪恶方式。这次我很确定它是固定的。我正在将变量Releases存储在中-(void)release
我没有意识到xCode会在需要时发布。我将所有变量版本移动到
-(void)Destroy
所以我可以释放MY命令中的所有内容。现在代码有效了。再次感谢!
答案 0 :(得分:1)
variable2
和variable3
在您提交模态视图之后实际访问它们(大概)之前会被自动释放。
至少将行改为:
self->variable2 = [[NSMutableArray arrayWithCapacity:1] retain];
self->variable3 = [[NSMutableArray arrayWithCapacity:1] retain];
或
self->variable2 = [[NSMutableArray alloc] initWithCapacity:1];
self->variable3 = [[NSMutableArray alloc] initWithCapacity:1];
variable1
应该没问题。
最好使用@property
和@synthesize
,这样您就可以使用点表示法:
<强>·H 强>
@interface MyClass : SuperClass
@property (nonatomic,retain) NSMutableArray *variable2;
@property (nonatomic,retain) NSMutableArray *variable3;
@end
<强>的.m 强>
@implementation MyClass
@synthesize variable2,varible3;
- (void)foo {
self.variable2 = [NSMutableArray arrayWithCapacity:1];
self.variable3 = [NSMutableArray arrayWithCapacity:1];
}
@end
答案 1 :(得分:1)
我建议您将variable1
,variable2
和variable3
声明为属性,而不是实例变量。然后,使用self.variable1
,self.variable2
和self.variable3
来访问它们。
点语法(self.variable1
等)使用您在每个属性上声明的内存管理策略;箭头语法(self->variable1
等)将直接访问变量。崩溃是因为您在远处创建了两个不会让您拥有它们的数组,然后没有将数组分配给保留它们的属性。
您可能还希望升级项目以使用ARC。然后没有内存管理差异;分配给实例变量而不是属性不会导致对象过早释放,因为ARC默认将实例变量视为所有权。您可能仍希望在切换到ARC后切换到使用属性,但不是为了防止崩溃。
回复您的修改:
我改变了将变量声明为@ property / @ synth以清理代码的方式,但它没有解决问题。
然后别的错了。
你从未对问题本身说过太多。你说你有一个EXC_BAD_ACCESS
,但没有什么声明引发了崩溃,或者你将它归咎于你所展示的代码的理由。
我改变了代码:
self.variable1 = [[NSNumber alloc] initWithInt:0];
但这是正确的代码。这就是你应该使用的东西。
到此:
self.variable1 = [NSNumber alloc]; [self.variable1 initWithInt:0];
不要!该代码在多个层面上是错误的,错误的,错误的。
init
方法(包括initWithWhatever:
方法)不保证返回您发送邮件的同一对象。 NSNumber的initWithInt:
很可能不。
该对象创建一个未初始化的 NSNumber对象,并将其分配给该属性。然后它将initWithInt:
发送给该对象,该对象将返回一个初始化对象,可以和很可能是一个不同的对象 。现在你拿着一个未初始化的对象(你稍后会尝试使用它)并将初始化的对象放在地板上。
永远不会在单独的表达式中发送alloc
和init
(With…
)。始终使用相同的表达式发送它们。没有例外。否则,您冒着保留未初始化对象而不是初始化对象的风险。在您的情况下(使用NSNumbers),几乎可以肯定会发生什么。
您应该做的是声明和合成拥有NSNumber对象的强属性,并在单个语句中创建NSNumber对象:[[NSNumber alloc] initWithInt:]
或[NSNumber numberWithInt:]
。如果您不使用ARC,则需要后者,因为该属性将保留该对象。如果您使用ARC,它们实际上是等效的。
如果你的代码崩溃,那么其他东西是错误的,所以请在这个问题或新问题中告诉我们 - 关于崩溃,以便我们可以帮助你找到它的真正原因。
答案 2 :(得分:0)
默认情况下,objective-c中的所有实例变量都具有受保护的范围。因此,除非您在接口文件中明确声明它们为:
@interface MYClass {
@public
NSNumber *variable1;
NSMutableArray *variable2;
NSMutableArray *variable3;
}
//...
@end
然后使用struct dereferencing运算符无法访问它们。这可能是导致EXC_BAD_ACCESS错误的原因。