Objective-C对象意外取消分配

时间:2010-02-05 14:42:04

标签: objective-c cocoa-touch

我是Objective-C的新手,我正在尝试开发一款iPhone应用程序。我的问题是当我在NSTimer中使用一个对象时,我收到“消息发送到解除分配的实例0x3d54830”错误。当我不使用NSTimer时,我可以正常使用该对象。例如:

//These can be any objects.  Le't say I have a Song class and a SongReader class in the header file SongTest.h
Song *song;
SongReader *reader;

NSTimer *timer;

- (void)justDoIt;


//In the implementation file SongTest.m
- (void)viewDidLoad {
    reader = [[SongReader alloc] init];
    song = [reader readSong];

    timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(justDoIt) userInfo:nil repeats:YES];
}

- (void)justDoIt {
    NSLog(@"This is a song integer property: %d", song.wordCount);
}

- (void)dealloc {
    [reader release];
    [super dealloc];
}

justDoIt方法/选择器/消息中的歌曲对象已根据调试器解除分配。我究竟做错了什么?即使我这样做:

song = [[reader readSong] retain]; //or
[song retain]; //or
[reader retain];

对象仍然意外取消分配。同样,问题只发生在我使用NSTimer时。就像在计时器触发之前对象被释放一样。

3 个答案:

答案 0 :(得分:2)

问题可能是NSTimer呼叫的目标(即“自我”)。因此,消息“justDoIt”被发送到解除分配的实例,该对象在代码中表示为“self”。

在计时器被触发之前是否取消分配控制器实例吗?

答案 1 :(得分:1)

您是否保留了SongTest对象?您没有显示该部分代码,但如果它是自动释放的,它将在计时器触发时释放。事实上,这正是错误信息所表明的:

  

“消息发送到解除分配的实例0x3d54830”

您正在创建计时器以将消息发送到“自我”,这是SongTest对象。

另外,你需要保留这首歌:

song = [[reader readSong] retain];

如果您根据标准Cocoa约定编写了--readSong。

答案 2 :(得分:0)

您应该使用属性来防止这些错误出现。如果您将歌曲定义为...

@property(nonatomic, retain)  Song *song;
...
@synthesize song;

...并像这样使用它......

self.song = [读者阅读];

... objective-c为您管理保留和释放,直到您调用dealloc。

与主要问题无关,计时器调用的方法应为......

-(void) arbitraryMethodName:(NSTimer *) aTimer;

...或者可能并不总是被正确调用。