2010-06-01 2 views
0

Часть этого приложения - кнопка «Scream», которая воспроизводит случайные крики от участников трансляции телешоу. Мне нужно время от времени натыкаться на приложение, чтобы увидеть утечку памяти в Инструментах, но она там, иногда поднимаясь (каждые 45 секунд до 2 минут). Утечка равна 3.50kb, когда это происходит. Не удалось взломать его несколько часов. Любая помощь оценивается.iphone: Справка с AudioToolbox Утечка: трассировка/код стека включены здесь

Instruments говорит, что это мешающий строка кода:

[appSoundPlayer play]; 

, который связан с линией 9 ниже трассировки стека:

0 libSystem.B.dylib таНос
1 libSystem. B.dylib pthread_create
2 AudioToolbox CAPThread :: Start()
3 AudioToolbox GenericRunLoopThread :: Start()
4 AudioToolbox AudioQueueNew (BOOL, AudioStreamBasicDescription сопз *, TCACallback Const &, CACallbackTarget Const &, беззнаковое долго, OpaqueAudioQueue **)
5 AudioToolbox AudioQueueNewOutput
6 AVFoundation allocAudioQueue (AVAudioPlayer *, AudioPlayerImpl *)
7 AVFoundation prepareToPlayQueue (AVAudioPlayer *, AudioPlayerImpl *)
8 AVFoundation - [AVAudioPlayer prepareToPlay]
9 Королевы крика - [ScreamViewController закричать:]/Users/laptop2/Desktop/Версии/Королевы крика ScreamQueens25/Крик Queens/Классы /../ ScreamViewController.m: 210
10 CoreFoundation - [N SObject performSelector: withObject: withObject:]
11 UIKit - [UIApplication sendAction: до: от: forEvent:]
12 UIKit - [UIApplication sendAction: toTarget: fromSender: forEvent:]
13 UIKit - [UIControl sendAction: в : forEvent:]
14 UIKit - [UIControl (внутренний) _sendActionsForEvents: withEvent:]
15 UIKit - [UIControl touchesEnded: withEvent:]
16 UIKit - [UIWindow _sendTouchesForEvent:]
17 UIKit - [UIWindow SendEvent: ]
18 UIKit - [UIApplication sendEvent:]
19 UIKit _UIApplicationHandleEvent
20 GraphicsServices PurpleEventCallback
21 CoreFoundation CFRunLoopRunSpecific
22 CoreFoundation CFRunLoopRunInMode
23 GraphicsServices GSEventRunModal
24 UIKit - [UIApplication _run]
25 UIKit UIApplicationMain
26 Королевы крика Основной/Пользователи/laptop2/Desktop/Королевы крика Версии/ScreamQueens25/Scream Queens/main.m: 14
27 Начало крика Куинз

Вот .h:

#import <UIKit/UIKit.h> 
#import <AVFoundation/AVFoundation.h> 
#import <MediaPlayer/MediaPlayer.h> 
#import <AudioToolbox/AudioToolbox.h> 
#import <MessageUI/MessageUI.h> 
#import <MessageUI/MFMailComposeViewController.h> 

@interface ScreamViewController : UIViewController <UIApplicationDelegate,  AVAudioPlayerDelegate, MFMailComposeViewControllerDelegate> { 





//AudioPlayer related 
AVAudioPlayer   *appSoundPlayer; 
NSURL     *soundFileURL; 
BOOL     interruptedOnPlayback; 
BOOL     playing; 

//Scream button related 
IBOutlet UIButton  *screamButton; 
int      currentScreamIndex; 
NSString    *currentScream; 
NSMutableArray   *screams; 
NSMutableArray   *personScreaming; 
NSMutableArray   *photoArray; 
int      currentSayingsIndex; 
NSString    *currentButtonSaying; 
NSMutableArray   *funnyButtonSayings; 
IBOutlet UILabel  *funnyButtonSayingsLabel; 
IBOutlet UILabel  *personScreamingField; 
IBOutlet UIImageView *personScreamingImage; 



//Mailing the scream related 
    IBOutlet UILabel  *mailStatusMessage; 
    IBOutlet UIButton  *shareButton; 


} 
//AudioPlayer related 
@property (nonatomic, retain) AVAudioPlayer     *appSoundPlayer; 
@property (nonatomic, retain) NSURL       *soundFileURL; 
@property (readwrite)   BOOL       interruptedOnPlayback; 
@property (readwrite)   BOOL       playing; 

//Scream button related 
@property (nonatomic, retain) UIButton      *screamButton; 
@property (nonatomic, retain) NSMutableArray     *screams; 
@property (nonatomic, retain) NSMutableArray     *personScreaming; 
@property (nonatomic, retain) NSMutableArray     *photoArray; 
@property (nonatomic, retain) UILabel       *personScreamingField; 
@property (nonatomic, retain) UIImageView      *personScreamingImage; 
@property (nonatomic, retain) NSMutableArray     *funnyButtonSayings; 
@property (nonatomic, retain) UILabel       *funnyButtonSayingsLabel; 


//Mailing the scream related 
@property (nonatomic, retain) IBOutlet UILabel     *mailStatusMessage; 
@property (nonatomic, retain) IBOutlet UIButton     *shareButton; 


//Scream Button 
- (IBAction) scream:     (id) sender; 

//Mail the scream 
- (IBAction) showPicker: (id)sender; 
- (void)displayComposerSheet; 
- (void)launchMailAppOnDevice; 


@end 

Вот верх.м:

#import "ScreamViewController.h" 

//top of code has Audio session callback function for responding to audio route changes (from Apple's code), then my code continues... 

@implementation ScreamViewController 

@synthesize appSoundPlayer;    // AVAudioPlayer object for playing the selected scream 
@synthesize soundFileURL;    // Path to the scream 
@synthesize interruptedOnPlayback;  // Was application interrupted during audio playback 
@synthesize playing;     // Track playing/not playing state 


@synthesize screamButton;    //Press this button, girls scream. 
@synthesize screams;     //Mutable array holding strings pointing to sound files of screams. 
@synthesize personScreaming;   //Mutable array tracking the person doing the screaming 
@synthesize photoArray;     //Mutable array holding strings pointing to photos of screaming girls 
@synthesize personScreamingField;  //Field updates to announce which girl is screaming. 
@synthesize personScreamingImage;  //Updates to show image of the screamer. 
@synthesize funnyButtonSayings;   //Mutable array holding the sayings 
@synthesize funnyButtonSayingsLabel; //Label that updates with the funnyButtonSayings 


@synthesize mailStatusMessage;   //did the email go out 
@synthesize shareButton;    //share scream via email 

Следующая строка начинается блок с кодом нарушившей:

- (IBAction) scream: (id) sender 
{ 
    //Play a click sound effect 
    SystemSoundID soundID; 
    NSString *sfxPath = [[NSBundle mainBundle] 
         pathForResource:@"aClick" ofType:@"caf"];  

    AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:sfxPath],&soundID); 
    AudioServicesPlaySystemSound (soundID); 


    // Because someone may slam the scream button over and over, 
    //must stop current sound, then begin next 
    if ([self appSoundPlayer] != nil) 
    { 
     [[self appSoundPlayer] setDelegate:nil]; 
     [[self appSoundPlayer] stop]; 
     [self setAppSoundPlayer: nil]; 

    } 


    //after selecting a random index in the array (did that in View Did Load), 
    //we move to the next scream on each click. 

    //First check... 
    //Are we past the end of the array? 

    if (currentScreamIndex == [screams count]) 
    { 
     currentScreamIndex = 0; 
    } 


    //Get the string at the index in the personScreaming array 

    currentScream = [screams objectAtIndex: currentScreamIndex]; 


    //Get the string at the index in the personScreaming array 
    NSString *screamer = [personScreaming objectAtIndex:currentScreamIndex]; 

    //Log the string to the console 
    NSLog (@"playing scream: %@", screamer); 

    // Display the string in the personScreamingField field 
    NSString *listScreamer = [NSString stringWithFormat:@"scream by: %@", screamer]; 

    [personScreamingField setText:listScreamer]; 


    // Gets the file system path to the scream to play. 
    NSString *soundFilePath = [[NSBundle mainBundle] pathForResource: currentScream 
                   ofType:    @"caf"]; 

    // Converts the sound's file path to an NSURL object 
    NSURL *newURL = [[NSURL alloc] initFileURLWithPath: soundFilePath]; 
    self.soundFileURL = newURL; 
    [newURL release]; 
    [[AVAudioSession sharedInstance] setDelegate: self]; 
    [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil]; 

    // Registers the audio route change listener callback function 
    AudioSessionAddPropertyListener (
            kAudioSessionProperty_AudioRouteChange, 
            audioRouteChangeListenerCallback, 
            self 
            ); 

    // Activates the audio session. 

    NSError *activationError = nil; 
    [[AVAudioSession sharedInstance] setActive: YES error: &activationError]; 

    // Instantiates the AVAudioPlayer object, initializing it with the sound 
    AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: soundFileURL error: nil]; 

    //Error check and continue 
    if (newPlayer != nil) 
    { 
     self.appSoundPlayer = newPlayer; 
     [newPlayer release]; 
     [appSoundPlayer prepareToPlay]; 
     [appSoundPlayer setVolume: 1.0]; 
     [appSoundPlayer setDelegate:self]; 
     //NEXT LINE IS FLAGGED BY INSTRUMENTS AS LEAKY 
     [appSoundPlayer play]; 
     playing = YES; 



     //Get the string at the index in the photoArray array 
     NSString *screamerPic = [photoArray objectAtIndex:currentScreamIndex]; 

     //Log the string to the console 
     NSLog (@"displaying photo: %@", screamerPic); 

     // Display the image of the person screaming 
     personScreamingImage.image = [UIImage imageNamed:screamerPic]; 

     //show the share button 
     shareButton.hidden = NO; 

     mailStatusMessage.hidden = NO; 
     mailStatusMessage.text = @"share!"; 



     //Get the string at the index in the funnySayings array 
     currentSayingsIndex = random() % [funnyButtonSayings count]; 
     currentButtonSaying = [funnyButtonSayings objectAtIndex: currentSayingsIndex]; 

     NSString *theSaying = [funnyButtonSayings objectAtIndex:currentSayingsIndex]; 
     [funnyButtonSayingsLabel setText: theSaying]; 

     currentScreamIndex++; 



    } 
} 

Вот мой dealloc:

- (void)dealloc { 
    [appSoundPlayer stop]; 
    [appSoundPlayer release], appSoundPlayer = nil; 
    [screamButton release], screamButton = nil; 
    [mailStatusMessage release], mailStatusMessage = nil; 
    [personScreamingField release], personScreamingField = nil; 
    [personScreamingImage release], personScreamingImage = nil; 
    [funnyButtonSayings release], funnyButtonSayings = nil; 
    [funnyButtonSayingsLabel release], funnyButtonSayingsLabel = nil; 
    [screams release], screams = nil; 
    [personScreaming release], personScreaming = nil; 
    [soundFileURL    release]; 

    [super dealloc]; 
} 


@end 

спасибо за чтение этого далеко! Любой вход оценивается.

ответ

3

Возможно, это красная селедка из инструмента «Утечки». См. Это сообщение в форумах dev: https://devforums.apple.com/message/119423#119423 Я «обнаруживаю» ту же самую утечку в инструменте утечек в моей реализации AVAudioPlayer, и я уверен, что мой код верен (в основном потому, что это так просто). Вот настоящий комментарий экспертов; он говорит о 3.5k, обнаруженном в [NSThread start], и у нас есть 3.5k [CAPThread :: Start()], но я думаю, что мы находимся в одной лодке:

«Проблема в том, что 3.5K вы видите, что в основном это структура данных, необходимая для того, чтобы ядро ​​отслеживало поток. В конце концов эта структура данных будет освобождена, но как только поток будет прекращен, в его пространстве процессов (только в ядре) больше нет ссылки на него ».

Я надеюсь, что это поможет.

+0

Rab, Спасибо! Похоже, ваше предположение было частью 1 из 2-х проблем, которые у меня были. Я не понимал, что у моих выходов есть счет на 2, текущий контроллер и супервизор. Я был только утечка памяти, когда представление «зависало», что означало, что я получал предупреждение с низкой памятью, представление было выгружено, но не было правильно освобождено. Изменение моего viewDidUnload и dealloc, чтобы больше походить на это, решило его: - (void) viewDidUnload { \t [appSoundPlayer release], appSoundPlayer = nil; [super viewDidUnload]; } - (void) dealloc { \t [appSoundPlayer release]; \t [super dealloc]; } –

+0

Рад, что вы решили! – Rab

Смежные вопросы