简体   繁体   English

懒惰的TableView图像加载Malloc错误

[英]Lazy TableView Image Loading Malloc Error

I am attempting to lazy load images onto my tableview, but I am getting a double free malloc error when I attempt to insert one specific image into my images array. 我试图将图像延迟加载到我的tableview上,但是当我尝试将一个特定图像插入到我的图像数组中时,我得到了一个双重的免费malloc错误。

This is the error: "Flags(8079,0xa0258540) malloc: * error for object 0x6a51b40: double free * set a breakpoint in malloc_error_break to debug". 这是错误:“Flags(8079,0xa0258540)malloc: *对象0x6a51b40的错误:double free *在malloc_error_break中设置断点以进行调试”。

Here is my code: 这是我的代码:

#import "ViewController.h"
#import "ASync.h"

@implementation ViewController
@synthesize tableView;
@synthesize countryNamesArray;
@synthesize receivedData; 
@synthesize flagImage;
@synthesize flagImagesArray;
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle
-(void)issueRequest:(NSString *)fullCountryImageURL{

    NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:fullCountryImageURL]
                                              cachePolicy:NSURLRequestUseProtocolCachePolicy
                                          timeoutInterval:60.0];
    // create the connection with the request
    // and start loading the data
    NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
    if (theConnection) {
        // Create the NSMutableData to hold the received data.
        // receivedData is an instance variable declared elsewhere.
        receivedData = [NSMutableData data];                                    
    } 
    else {
        // Inform the user that the connection failed.
    }
}

- (void)viewDidLoad
{   
    flagImagesArray = [[NSMutableArray alloc]init];
    for(int x=0; x<16; x++){
        [flagImagesArray insertObject:[UIImage imageNamed: @"jollyroger_poisonflag.jpg"] atIndex:x];

    }
    countryNamesArray=[[NSArray alloc] initWithObjects:@"India",@"USA",@"Antarctica",@"Brazil",@"Canada",@"China",@"France",@"Germany",@"Italy",@"Japan",@"Kenya",@"Malaysia",@"Mexico",@"South Africa",@"United Kingdom",@"Vietnam",nil];


    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } else {
        return YES;
    }
}

-(NSInteger)tableView:(UITableView *)tableview numberOfRowsInSection:(NSInteger)section{
    return 16;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    // This method is called when the server has determined that it
    // has enough information to create the NSURLResponse.

    // It can be called multiple times, for example in the case of a
    // redirect, so each time we reset the data.

    // receivedData is an instance variable declared elsewhere.
    [receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // Append the new data to receivedData.
    // receivedData is an instance variable declared elsewhere.
    [receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connectiondidFailWithError:(NSError *)error
{
    // release the connection, and the data object
    // receivedData is declared as a method instance elsewhere


    // inform the user
    NSLog(@"Connection failed! Error - %@ %@",
          [error localizedDescription],
          [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // do something with the data
    // receivedData is declared as a method instance elsewhere
    NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
    flagImage = [UIImage imageWithData: receivedData];
    if([receivedData length]==19935){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==0)
                [flagImagesArray replaceObjectAtIndex:0 withObject:flagImage];
        }
    }
    else if([receivedData length]==9280){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==1)
                [flagImagesArray replaceObjectAtIndex:1 withObject:flagImage];
        }
    }
    else if([receivedData length]==9567){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==2)
                [flagImagesArray replaceObjectAtIndex:2 withObject:flagImage];
        }
    }
    else if([receivedData length]==12152){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==3)
                [flagImagesArray replaceObjectAtIndex:3 withObject:flagImage];
        }
    }
    else if([receivedData length]==10903){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==4)
                [flagImagesArray replaceObjectAtIndex:4 withObject:flagImage];
        }
    }
    else if([receivedData length]==11298){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==5)
                [flagImagesArray replaceObjectAtIndex:5 withObject:flagImage];
        }
    }
    else if([receivedData length]==8682){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==6)
                [flagImagesArray replaceObjectAtIndex:6 withObject:flagImage];
        }
    }
    else if([receivedData length]==6865){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==7)
                [flagImagesArray replaceObjectAtIndex:7 withObject:flagImage];
        }
    }
    else if([receivedData length]==10567){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==8)
                [flagImagesArray replaceObjectAtIndex:8 withObject:flagImage];
        }
    }
    else if([receivedData length]==9423){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==9)
                [flagImagesArray replaceObjectAtIndex:9 withObject:flagImage];
        }
    }
    else if([receivedData length]==820){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==10)
                **[flagImagesArray replaceObjectAtIndex:10 withObject:flagImage];**
        }
    }
    else if([receivedData length]==12238){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==11)
                [flagImagesArray replaceObjectAtIndex:11 withObject:flagImage];
        }
    }
    else if([receivedData length]==5980){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==12)
                [flagImagesArray replaceObjectAtIndex:12 withObject:flagImage];
        }
    }
    else if([receivedData length]==10562){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==13)
                [flagImagesArray replaceObjectAtIndex:13 withObject:flagImage];
        }
    }
    else if([receivedData length]==9690){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==14)
                [flagImagesArray replaceObjectAtIndex:14 withObject:flagImage];
        }
    }
    else if([receivedData length]==11590){
        for (NSIndexPath *indexPath in [tableView indexPathsForVisibleRows]){
            if(indexPath.row==15)
                [flagImagesArray replaceObjectAtIndex:15 withObject:flagImage];
        }
    }


    [tableView reloadData];
}



-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *cellIdentifier = @"countryCell";
    static int numberOfRequests=0;
    UITableViewCell *cell=(UITableViewCell *) [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell==nil){
        cell=[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
    }

    // Create the request.

    NSString *flagImageURLPartOne = @"http://www.imageslink/";
    NSString *countryNumber = [NSString stringWithFormat:@"%i", indexPath.row];
    NSString *flagImageURLPartTwo = @".png";
    NSString *fullCountryImageURL = [NSString stringWithFormat:@"%@%@%@", flagImageURLPartOne, countryNumber, flagImageURLPartTwo];
    [self issueRequest:fullCountryImageURL];
    numberOfRequests++;



    cell.imageView.image=[flagImagesArray objectAtIndex:indexPath.row];
    cell.textLabel.text= [countryNamesArray objectAtIndex:indexPath.row];

    return cell;
}

-(void) tableView:(UITableView *) tableview didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}


@end

The line that is throwing the error is bolded - it is below the code line: "[flagImagesArray replaceObjectAtIndex:10 withObject:flagImage];". 抛出错误的行是粗体 - 它在代码行下面:“[flagImagesArray replaceObjectAtIndex:10 withObject:flagImage];”。 When I comment this line out, all the other images load fine. 当我评论这一行时,所有其他图像加载正常。 Anyone have any ideas as to what the problem is? 任何人都对问题是什么有任何想法?

Go to breakpoints tab, and on the lower left corner click the add button and select "Add Exception Breakpoint" and click done. 转到“断点”选项卡,在左下角单击“添加”按钮,然后选择“添加异常断点”并单击“完成”。

Run your code again, and you will find exactly when and where you are getting the crash, as well as all the debug information 再次运行您的代码,您将准确找到崩溃的时间和地点,以及所有调试信息

Only for completion's sake. 只是为了完成的缘故。

The problem is most probably with the image. 问题很可能与图像有关。 The image might be corrupted. 图像可能已损坏。 Using break points inside the 820 bracket will tell us where the error has occurred. 使用820括号内的断点将告诉我们错误发生的位置。

In cases like these. 在这样的情况下。 I always suggest doing a count on the data just to be sure about the data transferred from the server. 我总是建议对数据进行统计,以确保从服务器传输的数据。

And John solved the problem. 约翰解决了这个问题。 The problem was 问题是

I had one link that was pulling in a "Page Not Found" rather than an image. 我有一个链接在“找不到页面”而不是图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM