UIButtons事件Touch up Inside不正常工作?

3
我的问题有点含糊,这就是我发布所有代码的原因,所以我请求每个人在给我答案之前测试所有这些代码。谢谢。
在我的应用程序中,我通过编程方式创建所有UIButtons,然后将所有这些UIButtons保存在NSMutableArray中。以下是我的代码:
-(void)button:(id)sender
{
int btnn = 0;
int spacex = 152;
int spacey=20;
int k=0;
saveBtn = [[NSMutableArray alloc] init];
for (int i=0; i<48; i++)
      {
          if (btnn>6)
          {
              spacey=spacey+25;
              spacex = 152;
              btnn = 0;
          }
          else
          {
              btnn++ ;
              k++;
              UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
              btn.frame = CGRectMake(spacex, spacey, 25.0, 25.0);
              int idx;
              idx = arc4random()%[arr count];
              NSString* titre1 = [arr objectAtIndex:idx];
              [btn setTitle: titre1 forState: UIControlStateNormal];
              [btn setTitleColor: [UIColor yellowColor] forState: UIControlStateNormal];
              [btn.titleLabel setFont:[UIFont fontWithName:@"TimesNewRomanPS-BoldMT" size:22.0]];
              spacex = spacex + 25;
              btn.tag=k;
              [btn addTarget:self action:@selector(aMethod:)forControlEvents:UIControlEventTouchUpInside];
              [saveBtn addObject:btn];
              [self.view addSubview:btn];
        }
    }
}   

现在,在(aMethod:)中,我为每个UIButtonTouchUpInside事件添加了点击声音。以下是我的代码。

- (void)aMethod:(id)sender
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"button-17" ofType:@"wav"];
    AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
    theAudio.delegate=self;
    [theAudio play];
}

我的应用程序一开始运行得很好,但是在连续点击约100次UIButtons后,我听不到点击声,并且当我点击下一个UIButtons的touchup inside事件时,它会崩溃。有人可以帮我解决这个问题吗?谢谢。


2
崩溃时日志中有任何信息吗?这个问题并不像你想的那么奇怪 ;) - CodaFi
1
崩溃日志将有助于识别问题,同时您需要启用NSZombie,在这些情况下,大多数时间内存是崩溃的原因。 - rishi
感谢回复。当我点击“下一个”UIButton时,没有声音,并在NSLog中给出了异常信息:“终止应用程序,原因是未捕获的异常'NSInternalInconsistencyException',无法在包中加载NIB:'NSBundle </Users/moon/Library/Application Support/iPhone Simulator/4.1/Applications/3E14E5D6-4D1B-4DAC-A2B9-07667E99C399/soundtesting.app> (loaded)',名称为'secondclass'”。 - jamil
4个回答

2
由于未捕获的异常NSInternalInconsistencyException,应用程序出现问题:无法在包中加载NIB: NSBundle </Users/moon/Library/Application Support/iPhone Simulator/4.1/Applications/3E14E5D6-4D1B-4DAC-A2B9-07667E99C399/soundtesting.app‌​> (loaded),其名称为secondclass。这是一个命名问题,而不是按钮问题。你的UIButton(我只能假设它会将新视图推入堆栈)引用了一个不存在的NIB。最好检查任何调用-initWithNibName:的地方,并确认你的NIB是否真的命名为"secondclass"。请记住,iOS文件名区分大小写。
//.h
...
@property (nonatomic, retain) AVAudioPlayer * player;

//.m
-(void)viewDidLoad
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"button-17" ofType:@"wav"];
    player=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
    player.delegate=self;
    //in MRC, use [path release];
}

-(void)someMethod:(id)sender
{
    [player play];
}

谢谢,但是同样的代码对我来说很好用。在我的按钮变得静音或没有声音之前,它都能正常工作。 - jamil
1
是的,我相信你可能正在分配100个AVAudioPlayer实例。为什么不只有一个属性呢?这是一个内存问题。 - CodaFi
1
将您的audioPlayer设为属性,然后只需调用“-play”即可。 - CodaFi
@Albert,我已经编辑了一个例子。下次,请不要分配100个你将要重用的类实例!!! - CodaFi

1
可能的原因是由于多次播放相同的音频导致内存泄漏,使用以下代码来播放音频以避免内存占用。
- (id)initWithNibName:(NSString*)nibName bundle:(NSBundle*)nibBundleOrNil
{
    if (self = [super initWithNibName:nibName bundle:nibBundleOrNil]) {
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"button-17" ofType:@"wav"];
        theAudio = [AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:NULL];
    }
    return self;
}

- (IBAction)playSound
{
   [theAudio play];
}

- (void)dealloc
{
   [theAudio release];
   [super dealloc];
}

1

我测试了你的代码。在你的aMethod方法中更改了以下代码。通过这个,我可以获取标签值。

- (void)aMethod:(id)sender
{
    UIButton *btn=(UIButton *)sender;

    NSLog(@"\n\n\nselectedbutton tag === %d \n\n\n",btn.tag );

    NSString *path = [[NSBundle mainBundle] pathForResource:@"button-17" ofType:@"wav"];

    NSURL *url = [[NSURL alloc] initFileURLWithPath:path];
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
    audioPlayer.delegate = self;

    [audioPlayer prepareToPlay];
    [audioPlayer play];   
}

1

您有一个内存问题。当您执行以下操作时:

- (void)aMethod:(id)sender
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"button-17" ofType:@"wav"];
    AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
    theAudio.delegate=self;
    [theAudio play];
}

1/ path从未被释放
2/ theAudio从未被释放

因此,您需要在委托方法中释放theAudio:

– audioPlayerDidFinishPlaying:successfully:

并且您需要像这样释放path:

- (void)aMethod:(id)sender
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"button-17" ofType:@"wav"];
    AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
    theAudio.delegate=self;
    [theAudio play];
    [path release];
}

我认为您的问题应该得到解决。


1
不,更简单的方法是在 -viewDidLoad 中分配和设置属性,然后只需在该方法中调用 -play - CodaFi
当然!我以为每次声音都不同...太好了! - TheRonin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接