【问题标题】:How to tell if an object has been released如何判断一个对象是否已被释放
【发布时间】:2013-08-20 19:03:15
【问题描述】:

如何判断一个对象是否已被释放?

如果 UITableViewCell 已移出屏幕,则 kkcell 对象将被 UITableView 自动释放。

audioPlayer 结束后,程序调用“[kkcell stopSpeakAmination]”,但这会导致程序崩溃。

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{

    [kkcell stopSpeakAmination];
    playing=NO;
}

我也用

if(kkcell)

if(kkcell!=nil)

但它仍然崩溃。

这是我正在使用的更多代码:

//KKMessageCell2.m
....
@property(nonatomic, retain) UIImageView *SenderVoiceNodePlaying;
@property(nonatomic, retain) UIImageView *ReceiverVoiceNodePlaying;
....

-(void)stopSpeakAmination{
    [self.SenderVoiceNodePlaying stopAnimating];
    [self.ReceiverVoiceNodePlaying stopAnimating];
}

-(void)speakAminationOnRight:(UIButton*)btn{

    //rightside
    NSArray *speekImageAry = [[NSArray alloc]initWithObjects:
    [UIImage imageNamed:@"SenderVoiceNodePlaying001"],
    [UIImage imageNamed:@"SenderVoiceNodePlaying002"],
                          [UIImage imageNamed:@"SenderVoiceNodePlaying003"], nil];


    self.SenderVoiceNodePlaying.animationImages = speekImageAry; 
    self.SenderVoiceNodePlaying.animationDuration = 1.0; 
    self.SenderVoiceNodePlaying.animationRepeatCount = 0; 
    [self.SenderVoiceNodePlaying startAnimating];

    NSString *fileName=btn.titleLabel.text;
    fileName=[fileName substringFromIndex:10];
    KKMessageCell2 *cell=(KKMessageCell2*)[btn superview];
    [[NSNotificationCenter defaultCenter]postNotificationName:@"nPlayAmr"
                                    object:nil userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
                                                         fileName,@"fileName",
                                                         cell,@"cell",nil]];
}

//KKMessageCell2.m
....

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *identifier = @"msgCell";
    NSDictionary *dict = [messages objectAtIndex:indexPath.row];
    KKMessageCell2 *cell = [[[KKMessageCell2 alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    [cell setCellView:dict andMy_avatar_url:self.my_avatar_url];
    [cell.avatarLeftImageButton addTarget:self action:@selector(pushToUserDetail:) forControlEvents:UIControlEventTouchUpInside];
    [cell.avatarRightImageButton addTarget:self action:@selector(pushToUserDetail:) forControlEvents:UIControlEventTouchUpInside];
    [cell.chatphoto addTarget:self action:@selector(photoClick:) forControlEvents:UIControlEventTouchUpInside];
    return cell;

}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{

    [kkcell stopSpeakAmination];
    playing=NO;
}

【问题讨论】:

  • 首先要问的是,你用的是ARC吗?
  • 表格视图单元格在滚出屏幕时不会被释放,它会被放入重用队列。您确实需要发布更多代码,很难说出您要做什么。
  • 您能否显示您为kkcell 赋值的代码部分(即kkcell = ...;)?在 sn-p 中,您正在尝试使用它而不首先为其分配任何东西。这几乎总是会崩溃。
  • 这里没有足够的信息,但我的第一个猜测是您从未将AVAudioPlayer 委托属性设置为nil。为了向后兼容,AVAudioPlayer 委托属性设置为assignnot weak),因此如果您的对象在AVAudioPlayer 之前被释放,则需要手动将其设置为nil对象是,否则你会有一个悬空指针。
  • 您可以做的一个技巧是为您的单元类定义 dealloc 方法。如果您使用 ARC,则没有 [super dealloc];调用你重载的dealloc。这将让您看到您的单元格何时被释放。您还可以在 dealloc 中输出标识哪个单元格的信息,这可能会有所帮助。顺便说一句,如果您在 kkcell 上对 nil 的测试并不能防止出现问题,那么您的参考很有可能是悬空的。

标签: ios objective-c memory-management uitableview


【解决方案1】:

将您的项目转换为 ARC。它比您想象的要容易和自动化得多。我已经转换了大约 3 个在开发中期相当大且从未出现任何问题的现实生活项目(留出一小时来完成,您可能不需要那么多时间,而且绝对值得)

在 Xcode 中,选择 编辑->重构->转换为Objective-C ARC

您也可以在网上找到教程,但总体而言非常简单。

【讨论】:

    【解决方案2】:

    您的程序崩溃很可能是因为该对象确实已完全释放,但这并不意味着 kkcell 将设置为 nil,因此您的检查失败,kkcell 是“悬空的”。

    要回答您的具体问题,测试发布的一种方法是覆盖dealloc,如

    -(void)dealloc
    {
        NSLog(@"deallocated");
        [super dealloc];
    }
    

    这可以通过告诉您最终发布的确切时间来帮助您进行故障排除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多