Objective c 在UITableView中滚动时崩溃-对象意外释放

Objective c 在UITableView中滚动时崩溃-对象意外释放,objective-c,uitableview,Objective C,Uitableview,**注意:我已经根据aroth的建议更新了代码-但是它仍然崩溃。下面帖子中的代码是更新后的代码 我正在尝试创建一个基于表视图XCode模板(XCode 4)的iPhone应用程序。表格视图以正确的顺序填充正确的数据-但是当我滚动表格时,应用程序崩溃(有时我可以滚动5或10个以上的单元格,有时它会立即冻结)。表视图由NSArray中的“艺术家”对象提供,NSArray是另一个“iPodLibraryParser”对象的IVAR。我相信问题在于“iPodLibraryParser”对象被过早地释放了

**注意:我已经根据aroth的建议更新了代码-但是它仍然崩溃。下面帖子中的代码是更新后的代码

我正在尝试创建一个基于表视图XCode模板(XCode 4)的iPhone应用程序。表格视图以正确的顺序填充正确的数据-但是当我滚动表格时,应用程序崩溃(有时我可以滚动5或10个以上的单元格,有时它会立即冻结)。表视图由NSArray中的“艺术家”对象提供,NSArray是另一个“iPodLibraryParser”对象的IVAR。我相信问题在于“iPodLibraryParser”对象被过早地释放了——但我不明白为什么

我已使用以下头文件创建了iPodLibraryParser对象:

#import <Foundation/Foundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import <CoreLocation/CoreLocation.h>
#import "ArtistClass.h"

@interface iPodLibraryParser : NSObject {

    //Location stuff
    CLLocationManager *locationManager;
    IBOutlet UITextField *latitudeTextField;
    IBOutlet UITextField *longitudeTextField;
    IBOutlet UILabel *latitudeLabel;
    IBOutlet UILabel *longitudeLabel;

    //Music Library Stuff
    NSString *currentArtist;
    NSString *currentAlbum;
    NSMutableArray *artistArray;
    NSMutableArray *sortedArtistArray;       
}

@property (nonatomic, retain) NSMutableArray *sortedArtistArray;

-(void)parseiPodLibrary;
-(id) initializeiPodLibraryParser;

@end
艺术家对象标题:

#import <UIKit/UIKit.h>
#import "iPodLibraryParser.h"

@interface ArtistClass : NSObject {

    NSString *artistName;
    int numberOfTracks;

    id artistClassViewController;
}

-(id) initializeArtistObjectWithDocument:(id)myDocument withArtist:(NSString*) artist;

@property (nonatomic, retain) NSString *artistName;
@property (nonatomic, assign) int numberOfTracks;

@end
错误在这一行:

cell.textLabel.text = [[[iPodLibrary sortedArtistArray] objectAtIndex:indexPath.row] artistName];
我尝试用我在RootViewController中创建的Artister对象创建一个数组,效果非常好(可以滚动整个表而不会崩溃)

再次感谢

--编辑:

有趣的是,我在不同的时间会遇到不同的错误:

大多数情况下,这只是线路上的例外情况:

cell.textLabel.text = [[[iPodLibrary sortedArtistArray] objectAtIndex:indexPath.row] artistName];
有时是:

-[UIAutoRotatingWindow isEqualToString:]: unrecognized selector sent to instance 0x1baa80

另一个与无法识别的RGB选择器有关(非常奇怪)。

您的问题是当您执行此操作时:

SortedArray=[artistArray SortedArray使用描述符:排序数组]

sortedarrayingdescriptor
方法返回一个自动释放的对象,因此当它在没有警告的情况下被释放时,您不应该感到惊讶

此外,因为您的
init
执行以下操作:

sortedArray=[[NSArray alloc]init]

…而且,由于在分配给它之前没有释放它,因此您的代码正在泄漏NSArray实例。我建议作出以下修订:

  • 使
    sortedArray
    成为
    NSMutableArray*
    ,如:

    NSMutableArray*sortedarray

  • 不要覆盖
    parseiPodLibrary
    中的数组引用。相反,只需将排序后的数据集复制到可变数组中,如:

    -(void)parseiPodLibrary{
    
        //.....
    
        NSArray* temp = [artistArray sortedArrayUsingDescriptors:sortingArray];
        [sortedArtistArray removeAllObjects];
        [sortedArtistArray addObjectsFromArray:temp];
    
    }
    
  • 不要调用
    [iPodLibrary retain]
    视图中显示
    。您已经对其调用了alloc/init,因此无需再次保留它

  • 确保调用
    [iPodLibrary release]视图中的code>将消失
    ,并且
    [SortedArray release]dealloc
    中执行code>以避免内存泄漏


  • 我认为,您的
    iPodLibrary
    变量被过度释放的可能性要比数组释放的可能性大得多。您应该通过将代码分成几行并查看失败的地方来进行故障排除:

    NSArray *artistArray = [iPodLibrary sortedArtistArray];
    Artist *artist = [artistArray objectAtIndex:indexPath.row];
    NSString *name = [artist artistName];
    cell.textLabel.text = name;
    
    initializeiPodLibraryParser
    的实现是否可能返回自动释放的对象?不应该,因为这违反了公约。但这会导致这个问题,这是有道理的

    当你称之为:

    iPodLibrary = [[iPodLibraryParser alloc] initializeiPodLibraryParser];
    
    您直接分配的是
    iPodLibrary
    ivar,因此它的mutator不会被调用,属性标记为retain也不重要。如果您认为它被隐式保留,那么很可能您在其他地方过度发布了它。我发现,如果使用此样式分配属性,您将了解自己的内存管理:

    iPodLibraryParser *parser = [[iPodLibraryParser alloc] initializeiPodLibraryParser]; // retain count should be 1 if not autoreleased
    [self setIpodLibrary:parser]; // retain count is now 2
    [parser release]; // retain count is now 1, will go to zero when you release it in dealloc or viewDidUnload
    

    最后,我要将您的
    iPodLibrary
    初始化从
    viewDidAppear
    移动到
    viewDidLoad:
    。这就是您应该初始化视图的地方。您应该清理在
    viewDidUnload
    中初始化的所有内容,这些内容将在内存不足的情况下调用

    原来问题出在我的artist类中-artist字符串在我不知情的情况下被自动释放。将代码分成多行是一个巨大的帮助。谢谢大家!!!
    NSArray *artistArray = [iPodLibrary sortedArtistArray];
    Artist *artist = [artistArray objectAtIndex:indexPath.row];
    NSString *name = [artist artistName];
    cell.textLabel.text = name;
    
    iPodLibrary = [[iPodLibraryParser alloc] initializeiPodLibraryParser];
    
    iPodLibraryParser *parser = [[iPodLibraryParser alloc] initializeiPodLibraryParser]; // retain count should be 1 if not autoreleased
    [self setIpodLibrary:parser]; // retain count is now 2
    [parser release]; // retain count is now 1, will go to zero when you release it in dealloc or viewDidUnload