我将这两个按钮连接到这两个方法(它们几乎相同)
-(void)moveOneImageNewer{
int num = [numberOfImage intValue];
num--;
numberOfImage = [[NSString stringWithFormat:@"%i",num] retain];
//Load the image
[self loadImage];
}
-(void)moveOneImageOlder{
int num = [numberOfImage intValue];
num++;
numberOfImage = [NSString stringWithFormat:@"%i",num];
//Load the image
[self loadImage];
}
如果我两次击中其中任何一个(或者每次击中一次,基本上如果它们总共被调用两次),我会得到一个EXC_BAD_ACCESS。如果我抛出一个保留:numberOfImage = [[NSString stringWithFormat:@"%i",num]retain]
它很好。有人可以解释为什么会这样吗?我在乐器上做了一个NSZombie并追溯到这个stringWithFormat调用。提前谢谢!
答案 0 :(得分:2)
+ stringWithFormat:不包含'new','alloc','copy'或'retain',所以如果你想要它创建新的NSString,你应该期望你必须保留它的返回值坚持下去。
编辑包括这个方便的链接duskwuff亲切地挖出来:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH
答案 1 :(得分:2)
如果numberOfImage是正确声明的属性,例如
@property (copy) NSString *numberOfImage;
并且它已正确合成(在该类的@implementation部分中):
@synthesize numberOfImage;
然后你可以这样做:
- (void) moveOneImageNewer
{
self.numberOfImage = [NSString stringWithFormat: @"%i", [self.numberOfImage intValue] - 1];
// Load the image
[self loadImage];
}
属性设置器将负责保留字符串,并在必要时释放前一个字符串。
FWIW,为什么地球上的numberOfImage是字符串?为什么不是一个简单的int?
答案 2 :(得分:0)
numberOfImage是你班级的实例变量或属性,对吗?
您将其设置为stringWithFormat
(返回自动释放的NSString),而不声明该对象的所有权(通过调用retain)。
如果你不保留它,它将在再次调用方法之前自动释放(然后第一行将失败,因为它试图访问先前设置的,现在自动释放的值)。
考虑使用属性,它们具有自动生成的内存管理代码(包括在设置新的NSString时释放旧的NSString)。
答案 3 :(得分:0)
好吧,如果我是对的,NSString类方法“stringWithFormat”会返回一个autorelease NSString对象。
因此,对您的方法的第二次调用会使numberOfImage指向任何内容,因为它以前指向的自动释放NSString对象已经被释放并释放,因为您没有保留它。
当你第二次调用该方法时,直接导致崩溃的部分是[numberOfImage intValue]
,因为你向一个不再存在的对象(由numberOfImage指向)发送消息。
答案 4 :(得分:0)
您没有在“moveOneImageOlder”中保留字符串对象,因此该对象在事件周期结束时自动释放并指向空。这就是您下次尝试使用时获得EXC_BAD_ACCESS的原因。
使用retain声明NSString的所有权。记得在你完成后发布(你可以用属性来帮助你)
-(void)moveOneImageNewer{
int num = [numberOfImage intValue];
num--;
[numberOfImage release];
numberOfImage = [[NSString stringWithFormat:@"%i",num] retain];
//Load the image
[self loadImage];
}
-(void)moveOneImageOlder{
int num = [numberOfImage intValue];
num++;
[numberOfImage release];
numberOfImage = [[NSString stringWithFormat:@"%i",num] retain];
//Load the image
[self loadImage];
}
在dealloc中添加:
- (void)dealloc {
[numberOfImage release];
[super dealloc];
}