我是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时。就像在计时器触发之前对象被释放一样。
答案 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;
...或者可能并不总是被正确调用。