iPhone:如果分配给同一属性,多个Alloc是否会创建新对象?

iPhone:如果分配给同一属性,多个Alloc是否会创建新对象?,iphone,objective-c,memory-management,avaudioplayer,Iphone,Objective C,Memory Management,Avaudioplayer,由于我对OOP的世界还比较陌生,我想知道不断地将某些东西分配给某个属性可能会造成什么样的混乱 我有一个财产: @property (nonatomic, retain) AVAudioPlayer *audioPlayer; 然后在我的viewcontroller.m文件中合成。 现在,我有了一个初始化audioPlayer的方法,为它设置一个URL等等。让我担心的是,每次选择新声音时,我都会调用这个initialize方法,以允许用户播放拾取者发出的声音: self.audioPlayer

由于我对OOP的世界还比较陌生,我想知道不断地将某些东西分配给某个属性可能会造成什么样的混乱

我有一个财产:

@property (nonatomic, retain) AVAudioPlayer *audioPlayer;
然后在我的viewcontroller.m文件中合成。 现在,我有了一个初始化audioPlayer的方法,为它设置一个URL等等。让我担心的是,每次选择新声音时,我都会调用这个initialize方法,以允许用户播放拾取者发出的声音:

self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
上面的代码显示了每次更改选择器值时调用的行

在我喋喋不休之前,上面的a行是在每次我调用AVAudioPlayer对象时创建一个新的AVAudioPlayer对象实例,还是仅仅覆盖已经存在的audioPlayer实例? 如果是a,我怀疑我可以相当快地消除记忆;我该怎么做才能提高效率? 如果是b,我想那没关系吧? …如果你完全误解了物体是如何被创造出来的,那么请告诉我你的无知


谢谢

每次调用alloc时,它都会创建对象的新实例。但是,具有retain属性的属性将获取以前存储的值并调用release


对于引用计数,alloc/init=+1和release=-1。您需要做的是担心在使用完最后一个副本后创建的副本会减少。

每次调用alloc时,它都会创建一个新的对象实例。但是,具有retain属性的属性将获取以前存储的值并调用release


对于引用计数,alloc/init=+1和release=-1。您需要做的是担心在处理完后创建的最后一个副本会减少。

在分配新分配的对象时,应避免使用属性。例如,如果您的audioPlayer属性被合成为读取和写入名为mAudioPlayer的成员变量,则您应该执行以下操作:

mAudioPlayer = [[AVAudioPlayer] alloc] initWithContentsOfURL:fileURL error:nil]
如果由于副作用而必须使用该属性,请尝试以下操作:

AVAudioPlayer* audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
self.audioPlayer = audioPlayer;
[audioPlayer release];
这是安全的,因为该属性会自动保留新创建的对象,以便以后可以在本地释放它。因此,如果你按照你提到的方式做,就会出现漏洞。您将从alloc中得到一个引用2 1,从保留它的属性中得到一个引用。如果将self.audioPlayer设置为0或其他实例,则只需释放一次


希望有帮助。

在分配新分配的对象时,应避免使用属性。例如,如果您的audioPlayer属性被合成为读取和写入名为mAudioPlayer的成员变量,则您应该执行以下操作:

mAudioPlayer = [[AVAudioPlayer] alloc] initWithContentsOfURL:fileURL error:nil]
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
如果由于副作用而必须使用该属性,请尝试以下操作:

AVAudioPlayer* audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
self.audioPlayer = audioPlayer;
[audioPlayer release];
这是安全的,因为该属性会自动保留新创建的对象,以便以后可以在本地释放它。因此,如果你按照你提到的方式做,就会出现漏洞。您将从alloc中得到一个引用2 1,从保留它的属性中得到一个引用。如果将self.audioPlayer设置为0或其他实例,则只需释放一次

希望有帮助

self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
应为:

self.audioPlayer = [[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil] autorelease];

为了清晰起见,增加了一些细节

我想最让人困惑的部分是self.audioPlayer,对吗?将其视为一种方法可能会有所帮助,而setter实际上就是一种方法

这些线相当于:

self.audioPlayer = aPlayer;
[self setAudioPlayer:aPlayer];
由于属性设置为retain,因此方法setAudioPlayer中内置了一条[aPlayer retain]行。因此,如果你不释放一个玩家的本地副本,它将被保留两次

希望有帮助

self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
应为:

self.audioPlayer = [[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil] autorelease];

为了清晰起见,增加了一些细节

我想最让人困惑的部分是self.audioPlayer,对吗?将其视为一种方法可能会有所帮助,而setter实际上就是一种方法

这些线相当于:

self.audioPlayer = aPlayer;
[self setAudioPlayer:aPlayer];
由于属性设置为retain,因此方法setAudioPlayer中内置了一条[aPlayer retain]行。因此,如果你不释放一个玩家的本地副本,它将被保留两次

希望有帮助。

是c

self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
问题是,每次调用alloc时,创建的对象的保留计数都会增加到1。现在,当您使用self指定它时。考虑到你已经宣布该财产为

@property (nonatomic, retain) AVAudioPlayer *audioPlayer;
保留计数增加到2

将另一个对象指定给变量audioplayer时,旧实例的保留计数将递减1。因此,旧的物体只会泄漏

你需要的是

self.audioPlayer = [[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil] autorelease];
前提是您在dealloc方法中添加了对audioplayer的释放调用。

这是c

问题是,每次调用alloc时,创建的对象的保留计数都会增加到1。现在,当您使用self指定它时。考虑到你已经宣布该财产为

@property (nonatomic, retain) AVAudioPlayer *audioPlayer;
保留计数增加到2

当您分配另一个对象时 t对于变量audioplayer,旧实例的保留计数减少1。因此,旧的物体只会泄漏

你需要的是

self.audioPlayer = [[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil] autorelease];


如果您在dealloc方法中添加了对audioplayer的释放调用。

我犯了同样的错误,AVAudioPlayer对象将永远在那里,并且永远不会被释放,因为它们从alloc的retain+1开始,从合成的retain得到另一个。但是发布只会被调用一次。是的。所以模式应该是:alloc,分配给property,立即保留和释放。然后,在dealoc或viewDidUnload中释放最终副本,等等。我的问题是,我倾向于过度释放我不是出于偏执而创建的东西:这就是内存泄漏分析器和静态分析工具的形式!我犯了同样的错误,AVAudioPlayer对象将永远存在,并且永远不会被释放,因为它们从alloc的retain+1开始,从合成的retain得到另一个。但是发布只会被调用一次。是的。所以模式应该是:alloc,分配给property,立即保留和释放。然后,在dealoc或viewDidUnload中释放最终副本,等等。我的问题是,我倾向于过度释放我不是出于偏执而创建的东西:这就是内存泄漏分析器和静态分析工具的形式!答案是C。a行创建了一个新的AVAudioPlayer实例,b行覆盖了现有的音频播放器。答案是C。a行创建了一个新的AVAudioPlayer实例,b行覆盖了现有的音频播放器。谢谢,但是你能解释一下这一切是如何工作的吗?我举的第一个例子是,对象在应用程序生命的某个时刻自动释放?第二个是创建一个新实例,覆盖现有实例,然后释放临时实例,对吗?我想这似乎是最好的方法……谢谢,但你能解释一下这些方法是如何工作的吗?我举的第一个例子是,对象在应用程序生命的某个时刻自动释放?第二个是创建一个新实例,覆盖现有实例,然后释放临时实例,对吗?我想这似乎是最好的方法……是的,我确实在dealloc中有一个发布调用。谢谢可能会去读一读autorelease,这样我就知道它的实际功能了!:是的,我在dealloc有一个释放电话。谢谢可能会去读一读autorelease,这样我就知道它的实际功能了!:是的,您可能会将其添加到dealloc方法中。@Chutu它是有意义的,并且在第一次调用initialize函数时起作用。但是,当选择器值发生变化并再次调用时,它将在self.audioPlayer=audioPlayer上消失,程序接收到错误信号:“EXC_BAD_ACCESS”。另外,使用audioPlayer作为局部变量会给出一个警告“audioPlayer”的局部声明隐藏实例变量对不起,上面的错误是由于完全不同的原因造成的。显然是在做[文件路径发布];是谁造成的。真奇怪!谢谢大家但是,如果成员变量的名称与属性相同,则本地定义的audioPlayer将发出该警告。我倾向于在所有成员变量前面加上m,然后使用@synthesis关键字,如:@synthesis audioPlayer=mAudioPlayer;是的,您可能会将其添加到dealloc方法中。@Chutu它是有意义的,并且在第一次调用initialize函数时起作用。但是,当选择器值发生变化并再次调用时,它将在self.audioPlayer=audioPlayer上消失,程序接收到错误信号:“EXC_BAD_ACCESS”。另外,使用audioPlayer作为局部变量会给出一个警告“audioPlayer”的局部声明隐藏实例变量对不起,上面的错误是由于完全不同的原因造成的。显然是在做[文件路径发布];是谁造成的。真奇怪!谢谢大家但是,如果成员变量的名称与属性相同,则本地定义的audioPlayer将发出该警告。我倾向于在所有成员变量前面加上m,然后使用@synthesis关键字,如:@synthesis audioPlayer=mAudioPlayer;