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