UIViewController EXC_BAD_ACCES problem when popping

2

I'm trying to create a view controller which contains one table view with custom UITableViewCells in them that are editable. Now when I create the view controller and push it by the calling [self.navigationController pushController:animated:] it shows up just fine, and I can pop it away when I push the 'go back' button of the navigation controller. When I create it a second time, it displays well. But when I click it away a second time, my application crashes with the following stack frame:

#0  0x01087a67 in objc_msgSend
#1  0x04b6afb0 in ??
#2  0x00f1edb5 in +[__NSArrayI __new::]
#3  0x00f21661 in -[NSArray initWithArray:range:copyItems:]
#4  0x00e89833 in -[NSArray initWithArray:copyItems:]
#5  0x00f1ac9d in -[__NSArrayM copyWithZone:]
#6  0x00e867ca in -[NSObject(NSObject) copy]
#7  0x0038a643 in -[UINavigationController viewControllers]
#8  0x0038b68c in -[UINavigationController _shouldBottomBarBeHidden]
#9  0x0038d6b7 in -[UINavigationController _hideOrShowBottomBarIfNeededWithTransition:]
#10 0x00388277 in -[UINavigationController _popViewControllerWithTransition:allowPoppingLast:]
#11 0x0038841e in -[UINavigationController popViewControllerAnimated:]
#12 0x00387856 in -[UINavigationController navigationBar:shouldPopItem:]
#13 0x0032a104 in -[UINavigationBar _popNavigationItemWithTransition:]
#14 0x00332751 in -[UINavigationBar _handleMouseUpAtPoint:]
#15 0x002f60d1 in -[UIWindow _sendTouchesForEvent:]
#16 0x002d737a in -[UIApplication sendEvent:]
#17 0x002dc732 in _UIApplicationHandleEvent
#18 0x0185ba36 in PurpleEventCallback
#19 0x00f07064 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
#20 0x00e676f7 in __CFRunLoopDoSource1
#21 0x00e64983 in __CFRunLoopRun
#22 0x00e64240 in CFRunLoopRunSpecific
#23 0x00e64161 in CFRunLoopRunInMode
#24 0x0185a268 in GSEventRunModal
#25 0x0185a32d in GSEventRun
#26 0x002e042e in UIApplicationMain
#27 0x0000215e in main at main.m:25

Code for the implementation of StringEditorViewController:

Interface

#import <UIKit/UIKit.h>

#pragma mark -
#pragma mark String Editor Delegate
@class StringEditorViewController;
@protocol StringEditorDelegate
- (void)stringEditorWillEndEditing:(StringEditorViewController *)c;
- (void)stringEditorDidEndEditing:(StringEditorViewController *)c;
@end


#pragma mark -
#pragma mark Public Interface
@interface StringEditorViewController : UIViewController
    <UITableViewDelegate,
    UITableViewDataSource> {
    UITableView *mainTableView;

    id <StringEditorDelegate> _delegate;
    NSMutableArray *_strings;
}
#pragma mark Init
- (id)initWithStrings:(NSArray *)str delegate:(id <StringEditorDelegate>)del;

#pragma mark Properties
@property (nonatomic, retain) UITableView *mainTableView;

@property (nonatomic, assign) id <StringEditorDelegate> delegate;
- (void)setStrings:(NSArray *)ns;
- (NSArray *)strings;
@end

Implemnetation

#pragma mark -
#pragma mark Private Interface
@interface StringEditorViewController (PrivateMethods)
- (UIView *)createEditorViewWithTableView:(UITableView **)tv;
@end

#pragma mark -
#pragma mark Public Implementation
@implementation StringEditorViewController
#pragma mark Init and Dealloc
- (id)initWithStrings:(NSArray *)str delegate:(id <StringEditorDelegate>)del {
    self = [super init];
    if(self != nil) {
        UITableView *tv;
        UIView *newView = [self createEditorViewWithTableView:&tv];
        self.mainTableView = tv;
        self.view = newView;
        //[newView release];

        [self setDelegate:del];
        [self setStrings:str];
    }
    return self;
}

- (void)dealloc {
    [mainTableView release];
    [_strings release];

    [super dealloc];
}

#pragma mark Properties
@synthesize mainTableView;
@synthesize delegate=_delegate;
- (void)setStrings:(NSArray *)ns {
    if(ns = nil) {
        ns = [NSArray array];
    }

    if(_strings != ns) {
        [_strings release];
        _strings = [ns mutableCopy];
    }
}

- (NSArray *)strings {
    return [[_strings copy] autorelease];
}

#pragma mark Table View Data Source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    return nil;
}

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

#pragma mark Private Methods
- (UIView *)createEditorViewWithTableView:(UITableView **)tv {
    UIView *myView;
    UITableView *myTableView;
    CGRect viewFrame;

    viewFrame = [[UIScreen mainScreen] applicationFrame];
    myView = [[UIView alloc] initWithFrame:viewFrame];
    myTableView = [[UITableView alloc] initWithFrame:viewFrame];

    [myView addSubview:myTableView];
    [myTableView setDelegate:self];
    [myTableView setDataSource:self];
    [myTableView autorelease];

    if(tv) {
        *tv = myTableView;
    }

    return myView;
}
@end

I know I do not notify my delegate that the view will or did disappear and that I do not fill the UITableView, but it is not necessary to implement that right now.

If someone could help me with this, I would be very pleased. Thank you in advance, ief2

ios
uiviewcontroller
uinavigationcontroller
exc-bad-access
asked on Stack Overflow Jan 22, 2011 by v1Axvw • edited Jan 22, 2011 by v1Axvw

1 Answer

1

The error wasn't to be found in the displaying of the view controller, but in my implementation of the -viewWillAppear: and the -viewWillDisappear: method of the view controller which shows the view controller. In that view controller I notify a delegate, and that delegate did release the view controller. So when the view controller pops twice, once when the view disappears the first time and once when the view disappears a second time, the view controller get's deallocated because it's delegate released it twice. When the navigation controller tries to access this view controller, which has just been deallocated, the program of course crashes.

answered on Stack Overflow Jan 23, 2011 by v1Axvw

User contributions licensed under CC BY-SA 3.0