2010-02-05 76 views
0

我对Objective-C非常陌生,我试图开发一个iPhone应用程序。我的问题是当我在一个NSTimer中使用一个对象时,我得到了“消息发送到解除分配的实例0x3d54830”的错误。当我不使用NSTimer时,我可以很好地使用该对象。例如:Objective-C对象意外解除分配

//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

顺便说一句,请认为没有语法错误。问题是围绕对象释放(运行时)。这不是编译器错误。 – tonex 2010-02-05 14:43:48

回答

1

你保留你的SongTest对象吗?你不会显示那部分代码,但是如果它是自动发布的,它将在计时器触发时解除分配。事实上,这真的是错误消息表明:

“的消息发送到释放实例0x3d54830”

要创建的计时器将消息发送到“自我”,这是SongTest目的。

此外,你需要保留歌曲:

song = [[reader readSong] retain]; 

如果你按照标准可可约定编码-readSong。

+0

嘿,dodgio。我知道我说过“song = [[reader readSong] retain]”不适合我,但我在你这么说之后再次尝试过。现在,它的工作。另外,我明确释放SongTest。我不必保留它。 谢谢,伙计! – tonex 2010-02-05 15:42:26

2

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

控制器实例是否在定时器被触发前解除分配?

+0

感谢您的回复。控制器实例未取消分配。实际上,所有其他实例变量都可以在“justDoIt”消息中访问。这只是我遇到问题的特定对象。 – tonex 2010-02-05 15:28:39

+0

嗨,肯。我非常感谢你的帮助。我找到了答案 - 请参阅dodgio的回复。谢谢! – tonex 2010-02-05 15:44:54

0

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

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

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

self.song = [读者readSong]

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

无关你的主要问题,由定时器叫应该是形式的方法...

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

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

+0

你可能是对的TechZen。我不想使用属性,因为我认为它更耗费资源。但现在我明白你的观点。我也会试试这个。 – tonex 2010-02-06 16:24:34