2012-12-19 21 views
5

मैं अपने ऐप में हर बटन क्लिक पर एक क्लिक ध्वनि चलाने के लिए उसके लिए कोशिश कर रहा हूँ मैं एक उपयोगिता वर्ग जिसका ज और मीटर हैस्मृति रिसाव जब बनाए रखने संपत्ति

ज फ़ाइल इस प्रकार बनाया

@interface SoundPlayUtil : NSObject<AVAudioPlayerDelegate,AVAudioSessionDelegate> 
{ 
    AVAudioPlayer *audioplayer; 
} 
@property (retain, nonatomic) AVAudioPlayer *audioplayer; 
-(id)initWithDefaultClickSoundName; 
-(void)playIfSoundisEnabled; 
@end 

मीटर फ़ाइल

@implementation SoundPlayUtil 
@synthesize audioplayer; 

-(id)initWithDefaultClickSoundName 
{ 
self = [super init]; 
    if (self) 
{ 
    NSString* BS_path_blue=[[NSBundle mainBundle]pathForResource:@"click" ofType:@"mp3"]; 
    self.audioplayer =[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:BS_path_blue] error:NULL]; 
    [self.audioplayer prepareToPlay]; 
} 
return self; 
} 

-(void)playIfSoundisEnabled 
{ 
if ([[NSUserDefaults standardUserDefaults] boolForKey:soundStatus]==YES) 
{ 
    [self.audioplayer play]; 
} 
} 

-(void)dealloc 
{ 
[audioplayer release]; 
[super dealloc]; 
} 
@end 

और किसी भी वर्ग पर बटन पर क्लिक मैं

कर रहा हूँ

यह काम कर रहा है और मैं ध्वनि बजाने में सफल रहा। जब मैं कोड का विश्लेषण करता हूं तो समस्या उत्पन्न होती है। कंपाइलर दिखाता है कि में मेडिट रिसाव है initWithDefaultClickSoundName उपयोगिता वर्ग के एमएम में विधि क्योंकि मैं self.audioplayer पर आवंटन विधि भेज रहा हूं और इसे जारी नहीं कर रहा हूं।

इस ऑब्जेक्ट को जारी करने का सबसे अच्छा स्थान क्या है?

+0

आप एआरसी का उपयोग कर रहे हैं? –

+0

नहीं, त्वरित उत्तर के लिए एआरसी –

उत्तर

2

समस्या तब होती है जब आप उस वस्तु को आवंटित करते हैं जो इसे बनाए रखता है गणना 1 होगी, आप उस ऑब्जेक्ट को एक संपत्ति वस्तु को बनाए रखने के लिए निर्दिष्ट कर रहे हैं।

- (void)setAudioplayer: (id)newValue 
{ 
    if (audioplayer != newValue) 
    { 
     [audioplayer release]; 
     audioplayer = newValue; 
     [audioplayer retain]; 
    } 
} 

बदलें:: तो फिर इसे फिर से वस्तु अपने पास रखेंगे इसलिए retainCount हो जाएगा 2.

एक संपत्ति को बनाए रखने के सेटर कोड की तरह कुछ है

self.audioplayer =[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:BS_path_blue] error:NULL]; 

की तरह;

self.audioplayer =[[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:BS_path_blue] error:NULL] autorelease]; 

या की तरह:

AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:BS_path_blue] error:NULL]; 
self.audioplayer = player; 
[player release]; 
+0

धन्यवाद का उपयोग नहीं, मैं autorelease से बचने की कोशिश कर रहा हूं, इसलिए यदि मैंने आपके द्वारा दिया गया दूसरा विकल्प लागू किया है। उस स्थिति में मैंने ** self.audioplayer ** को बनाए रखा है और ऑडिओप्लेयर ऑब्जेक्ट की गिनती बरकरार रखी है 1. अब मैं इसे नए ऑब्जेक्ट ** प्लेयर ** को सौंप रहा हूं जिसका रखरखाव गिनती भी है 1. क्या यह मामला होगा कि मैं ** self.audioplayer ** को नया मान निर्दिष्ट करने के बाद गिनती 1 को बनाए रखने के साथ ऑब्जेक्ट का संदर्भ खो रहा हूं ?? –

+0

उसके बाद मैं अस्थायी वस्तु को जारी कर रहा हूं।इसलिए यह कोई अनाथ नहीं बनाएगा या रिसाव का कारण नहीं होगा –

+0

ऑटोोरलीज से बचें क्यों? एक ध्वनि वस्तु को रन लूप के माध्यम से एक से अधिक पास रहने के लिए बहुत अधिक गारंटी दी जाती है और ध्वनि बजाने की ऑटोरेलीज बनाम लागत नगण्य है। ध्यान दें कि रखरखाव की गणना आवंटन पर 1 हो सकती है या नहीं भी हो सकती है। निरंतर बनाए रखने की गणना व्यर्थ हैं। – bbum

0
self.audioplayer =[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:BS_path_blue] error:NULL]; 

यहाँ, आप एक नई वस्तु बनाने, तो यह एक बनाए रखा संपत्ति के लिए आवंटित। हालांकि, संपत्ति के अलावा, आपके पास ऑब्जेक्ट का कोई संदर्भ नहीं है, इसलिए यह लीक हो जाता है। आपने दो बार बरकरार रखी है।

वरीयता के क्रम में ठीक करने के लिए,: चाप को

  1. Convert;)
  2. एक स्थानीय चर बनाएँ, संपत्ति के लिए असाइन करें, फिर उसे छोड़।

    Object *object = [[Object alloc] init]; 
    self.property = object; 
    [object release]; 
    
  3. ऑब्जेक्ट में एक autorelease कॉल जोड़ें के रूप में आप यह जोड़ रहे हैं: self.property = [[[Object alloc] init] autorelease];

संबंधित मुद्दे