"EXC_BAD_ACCESS", "- [Save CFString]: message sent to the freed instance" when scrolling through the table

DESCRIPTION OF THE APPLICATION . I am a new iPhone developer. I am working on an application that used two kinds of tables, and then a detailed view. The first level table view presents several categories, when a category is selected, a list of topics related to this category is displayed. When a theme is selected, a detailed view is presented associated with this theme.

When I run the application in the simulator, everything works fine (but only for a short while!):

  • First level table: this view with the category loads perfectly and works without problems.
  • View topic list: This view also works fine, but only for a short while. It downloads all the correct themes, and I can even quickly scroll up and down the entire list of topics, but this only works for a couple of seconds when scrolling (after which the application crashes). I can also select any of the topics and upload a detailed view.
  • Detailed view: working fine, no problem.

I use two applications for the application: MainWindow.xib displays the first level tables and themes. The themeDetail.xib is used to display detailed information for the theme.

The DATA: . The first level of viewing gets its data from plist, which consists of an array of strings. Viewing a list of topics gets its data from the dictionary layer. Each dictionary consists of five lines. One of these lines contains “Tags” for categories that relate to the topic. When a category is selected from a first-level view, in the "Topic" section, topics are selected with "Tags" that correspond to the selected category, and displays them in the "View Topic" table.

PROBLEM: My problem is with the second "View Topic". A few ways I was able to cause a crash:

  • If I quickly scroll up and down the list of topics, everything will work fine in a couple of seconds, then the application will work.

  • , . ( , ), .

: , , EXC_BAD_ACCESS. NSZombieEnabled, " - [ CFString]: ,

, , , "" , , , ! - !

CODE:

View Controller.h:

#import 
@class TopicListController;

@interface FirstLevelViewController : UITableViewController {
    NSArray *controllers;
    TopicListController *childController;
}
@property (nonatomic, retain) NSArray *controllers;
@end

.m:


#import "FirstLevelViewController.h"
#import "TopicListController.h"
#import "TopicAppDelegate.h"

@implementation FirstLevelViewController
@synthesize controllers;

- (void)viewDidLoad
{
    self.title = @"Categories"; 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"TopicCategoryList" ofType:@"plist"];  
    NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:path];   
    self.controllers = array;
    [array release];
    [super viewDidLoad];
}

- (void)viewDidUnload
{
    self.controllers = nil;
    [childController release];
    childController = nil;
    [super viewDidUnload];
}

- (void) dealloc
{
    [controllers release];
    [childController release];
    [super dealloc];
}

#pragma mark -
#pragma mark Table Data Source Methods

- (NSInteger)tableView:(UITableView *)tableview numberOfRowsInSection:(NSInteger)section
{
    return [self.controllers count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *FirstLevelCell = @"FirstLevelCell";    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:FirstLevelCell];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:FirstLevelCell] autorelease];
    }
    NSUInteger row = [indexPath row];
    cell.textLabel.text = [controllers objectAtIndex:row];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    return cell;
}

#pragma mark -
#pragma mark Table View Delegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (childController == nil) {
        childController = [[TopicListController alloc] init];
    }

    childController.title = @"Topics";
    NSUInteger row = [indexPath row];

    NSString *selectedCategory = [self.controllers objectAtIndex:row];
    childController.selectedCategory = selectedCategory;
    [self.navigationController pushViewController:childController animated:YES];
}                            

@end

Controller.h:

#import 
@class TopicDetailController;

@interface TopicListController : UITableViewController {

    NSArray *list;
    NSString *selectedCategory;
    TopicDetailController *childController;

}

@property (nonatomic, retain) NSArray *list;
@property (nonatomic, retain) NSString *selectedCategory;

@end

.

#import "TopicListController.h"
#import "TopicAppDelegate.h"
#import "TopicDetailController.h"
#import "NSArray-MutableDeepCopy.h"
#import "TopicConstants.h"

@implementation TopicListController

@synthesize list;
@synthesize selectedCategory;

- (void)viewWillAppear:(BOOL)animated
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"TopicContent" ofType:@"plist"];

    NSMutableArray *fullArray = [[NSMutableArray alloc] initWithContentsOfFile:path];   
    NSMutableArray *fullArrayCopy = [fullArray mutableDeepCopy];

    NSUInteger items = [fullArrayCopy count];
    NSUInteger item=0;

        for (item; item /*less than*/ items; item++) {
            if ([[[fullArrayCopy objectAtIndex:item] objectForKey:CATEGORIES_KEY] 
             rangeOfString:selectedCategory 
             options:NSCaseInsensitiveSearch].location == NSNotFound) 
        {
            [fullArrayCopy removeObjectAtIndex:item];
            item--;
            items--;
        }
    }

    self.list = fullArrayCopy;
    [fullArray release];
    [self.tableView reloadData];
    [super viewWillAppear:animated];
}

- (void)viewDidUnload
{
    self.list = nil;
    self.selectedCategory = nil;
    [childController release];
    childController = nil;
}

- (void)dealloc
{
    [list release];
    [selectedCategory release];
    [childController release];
    [super dealloc];
}

#pragma mark -
#pragma mark Table Data Source Methods

- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section
{
    return [list count];
}

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath
{
    static NSString *DisclosureButtonCellIdentifier = @"DisclosureButtonCellIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:DisclosureButtonCellIdentifier];

    if (cell==nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:DisclosureButtonCellIdentifier]
                autorelease];
    }

    NSUInteger row = [indexPath row];
    NSString *rowString = [[list objectAtIndex:row] objectForKey:TITLE_KEY];
    NSString *rowDetailString = [[list objectAtIndex:row] objectForKey:SUBTITLE_KEY];
    cell.textLabel.text = rowString;
    cell.detailTextLabel.text = rowDetailString;
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
    [rowString release];
    [rowDetailString release];
    return cell;
}

#pragma mark -
#pragma mark Table Delegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (childController == nil) {
        childController = [[TopicDetailController alloc] initWithNibName:@"TopicDetail" bundle:nil];
    }


    NSUInteger row = [indexPath row];

    NSString *selectedTopicInformation = [[list objectAtIndex:row] objectForKey:INFORMATION_KEY];
    NSString *selectedTopicTitle = [[list objectAtIndex:row] objectForKey:TITLE_KEY];
    NSString *selectedTopicSubtitle = [[list objectAtIndex:row] objectForKey:SUBTITLE_KEY];
    NSString *selectedTopicTips = [[list objectAtIndex:row] objectForKey:TIPS_KEY];

    NSString *detailMessageInformation  = [[NSString alloc] initWithFormat:@"%@.", selectedTopicInformation];
    NSString *detailMessageTitle = [[NSString alloc] initWithFormat:@"%@", selectedTopicTitle];
    NSString *detailMessageSubtitle = [[NSString alloc] initWithFormat:@"%@", selectedTopicSubtitle];
    NSString *detailMessageTips = [[NSString alloc] initWithFormat:@"%@", selectedTopicTips];

    childController.messageInformation = detailMessageInformation;
    childController.messageTitle = detailMessageTitle;
    childController.messageSubTitle = detailMessageSubtitle;
    childController.messageTips = detailMessageTips;

    childController.title = @"Topic Detail";

    [detailMessageInformation release];
    [detailMessageTitle release];
    [detailMessageSubtitle release];
    [detailMessageTips release];
    [self.navigationController pushViewController:childController animated:YES];


}

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
    if (childController == nil) {
        childController = [[TopicDetailController alloc] initWithNibName:@"TopicDetail" bundle:nil];
    }

    NSUInteger row = [indexPath row];

    NSString *selectedTopicInformation = [[list objectAtIndex:row] objectForKey:INFORMATION_KEY];
    NSString *selectedTopicTitle = [[list objectAtIndex:row] objectForKey:TITLE_KEY];
    NSString *selectedTopicSubtitle = [[list objectAtIndex:row] objectForKey:SUBTITLE_KEY];
    NSString *selectedTopicTips = [[list objectAtIndex:row] objectForKey:TIPS_KEY];

    NSString *detailMessageInformation  = [[NSString alloc] initWithFormat:@"%@.", selectedTopicInformation];
    NSString *detailMessageTitle = [[NSString alloc] initWithFormat:@"%@", selectedTopicTitle];
    NSString *detailMessageSubtitle = [[NSString alloc] initWithFormat:@"%@", selectedTopicSubtitle];
    NSString *detailMessageTips = [[NSString alloc] initWithFormat:@"%@", selectedTopicTips];

    childController.messageInformation = detailMessageInformation;
    childController.messageTitle = detailMessageTitle;
    childController.messageSubTitle = detailMessageSubtitle;
    childController.messageTips = detailMessageTips;

    childController.title = @"Topic Detail";

    [detailMessageInformation release];
    [detailMessageTitle release];
    [detailMessageSubtitle release];
    [detailMessageTips release];
    [self.navigationController pushViewController:childController animated:YES];
}

@end
+3
1

tableView:cellForRowAtIndexPath:. :

[rowString release];
[rowDetailString release];

:

NSString *rowString = [[list objectAtIndex:row] objectForKey:TITLE_KEY];
NSString *rowDetailString = [[list objectAtIndex:row] objectForKey:SUBTITLE_KEY];

. -, , , , , . , , - objective-c . :

  • , .
  • , .
  • , . ( - alloc/init).
+10

Source: https://habr.com/ru/post/1779642/


All Articles