我使用three20来创建图像查看器。首先,我从sql数据库创建相册列表,当用户选择任何相册时,其url字符串将传递给此代码,该代码使用XML Parser在网络上创建可用图片的thums。一切工作正常,但用户返回到专辑列表并选择另一个专辑。应用程序崩溃'线程1:程序收到信号:“EXC + BAD_ACCESS”在main.m。加上XCode产品分析给出了潜在的内存泄漏,我在viewDidLoad中创建photoSource。下面是代码回到相册列表时,内存泄漏和应用程序崩溃
#import "AlbumController.h"
#import "PhotoSource.h"
#import "Photo.h"
#import "AlbumInfo.h"
#import "AlbumDatabase.h"
@implementation AlbumController
@synthesize albumName;
@synthesize urlAddress;
@synthesize images;
- (void)viewDidLoad
{
[super viewDidLoad];
// NSLog(@"%@", self.urlAddress);
[self createPhotos]; // method to set up the photos array
self.photoSource = [[PhotoSource alloc]
initWithType:PhotoSourceNormal
title:self.albumName
photos:images
photos2:nil];
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// release and set to nil
}
-(void)createPhotos
{
if ([stories count] == 0)
{
NSString *path = self.urlAddress;
[self parseXMLFileAtURL:path];
}
images = [NSMutableArray arrayWithCapacity:[stories count]]; // needs to be mutable
for (int i = 0; i < [stories count]; i++)
{
NSString *img = [[stories objectAtIndex:i] objectForKey:@"image"];
img = [img stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
//NSString * caption = [[stories objectAtIndex:i] objectForKey:@"caption"];
//caption = [caption stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
[images addObject:[[[Photo alloc] initWithURL:img smallURL:img size:CGSizeMake(320, 212)] autorelease]];
}
}
#pragma mark -
#pragma mark XML Parser Implementation
- (void)parserDidStartDocument:(NSXMLParser *)parser{
//NSLog(@"found file and started parsing");
}
- (void)parseXMLFileAtURL:(NSString *)URL
{
stories = [[NSMutableArray alloc] init];
//you must then convert the path to a proper NSURL or it won't work
NSURL *xmlURL = [NSURL URLWithString:URL];
// here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error
// this may be necessary only for the toolchain
rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[rssParser setDelegate:self];
// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:@"Unfortunately it is not possible to load Pictures. Please check Internet Connection. (Error code %i)", [parseError code]];
//NSLog(@"error parsing XML: %@", errorString);
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@"Failed to load the feed." message:errorString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[errorAlert show];
[errorAlert release];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
//NSLog(@"found this element: %@", elementName);
currentElement = [elementName copy];
if ([elementName isEqualToString:@"item"]) {
// clear out our story item caches...
item = [[NSMutableDictionary alloc] init];
currentCaption = [[NSMutableString alloc] init];
//currentThumbnail = [[NSMutableString alloc] init];
currentImage = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
//NSLog(@"ended element: %@", elementName);
if ([elementName isEqualToString:@"item"]) {
// save values to an item, then store that item into the array...
//[item setObject:currentThumbnail forKey:@"thumbnail"];
//[item setObject:currentCaption forKey:@"caption"];
[item setObject:currentImage forKey:@"image"];
[stories addObject:[[item copy] autorelease]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
// save the characters for the current item...
if ([currentElement isEqualToString:@"thumbnail"]) {
//[currentThumbnail appendString:string];
}// else if ([currentElement isEqualToString:@"caption"]) {
//[currentCaption appendString:string];
//}
else if ([currentElement isEqualToString:@"image"]) {
[currentImage appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
NSLog(@"all done!");
NSLog(@"stories array has %d items", [stories count]);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
return YES;
}
else
{
return NO;
}
}
#pragma mark -
#pragma mark Memory Management
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
[currentElement release];
[rssParser release];
[stories release];
[item release];
[currentCaption release];
//[currentThumbnail release];
[currentImage release];
[images release];
[stories release];
[super dealloc];
}
@end
这里是didSelectRowAtIndexPath方法这就是推动这一观点
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
AlbumInfo *info = [_albumInfos objectAtIndex:indexPath.row];
AlbumController *albumController = [[AlbumController alloc] init];
albumController.urlAddress = info.address;
albumController.albumName = info.name;
[self.navigationController pushViewController:albumController animated:YES];
[albumController release];
}
这里使用本教程http://www.raywenderlich.com/1430/how-to-use-the-three20-photo-viewer
为AlbumController.h
#import <Foundation/Foundation.h>
#import "Three20/Three20.h"
@interface AlbumController : TTThumbsViewController <NSXMLParserDelegate>
{
NSString *albumName;
NSString *urlAddress;
// images
NSMutableArray *images;
// parser
NSXMLParser * rssParser;
NSMutableArray * stories;
NSMutableDictionary * item;
NSString * currentElement;
NSMutableString * currentImage;
NSMutableString * currentCaption;
}
@property (nonatomic, strong) NSString *albumName;
@property (nonatomic, strong) NSString *urlAddress;
@property (nonatomic, retain) NSMutableArray *images;
- (void)createPhotos;
- (void)parseXMLFileAtURL:(NSString *)URL;
@end
代码需要帮助解决这个内存泄漏,并需要知道为什么它的崩溃ING。
谢谢
启用NSZombie环境变量,看看你发送消息到发布的对象。 self.photoSource有哪些属性?保留还是分配? – 0x8badf00d 2012-02-06 00:30:12
我还没有申报self.photoSource的任何财产,你能指导我通过NSZombie的东西。以前从未使用过。 – Hitz 2012-02-06 03:18:02
事情是,如果我从didSelectRowAtIndexPath中删除albumController版本,那么应用程序工作正常,但在产品分析期间,我得到内存泄漏。 – Hitz 2012-02-06 03:25:35