2

我想创建一个视图控制器,其中包含一个表视图与自定义UITableViewCells在他们是可编辑的。现在,当我创建视图控制器并通过调用[self.navigationController pushController:animated:]来推送它时,它显示得很好,当我按下导航控制器的“返回”按钮时,我可以弹出它。当我第二次创建它时,它显示得很好。但是,当我点击它走第二次,我的应用程序崩溃与下面的堆栈帧:UIViewController EXC_BAD_ACCES问题时弹出

#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 

代码StringEditorViewController实施:

接口

#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 

我知道我没有通知我的委托,该视图将会或者确实消失,而且我没有填充UITableView,但是现在没有必要执行该操作。

如果有人能帮助我,我会很高兴。谢谢你在前进, ief2

+0

@ lef2为什么你在`-dealloc`中发送'retain`消息给你的ivars?你一定要发送`release`消息。 – 2011-01-22 20:08:24

回答

1

错误没有在视图控制器的显示被发现,但在我执行-viewWillAppear:和视图控制器,显示视图控制器的-viewWillDisappear:方法。在那个视图控制器中,我通知一个委托,并且该委托确实释放了视图控制器。所以当视图控制器弹出两次时,一次当视图第一次消失,一次当视图第二次消失时,视图控制器得到解除分配,因为它是委托释放它两次。当导航控制器尝试访问刚刚被释放的视图控制器时,程序当然会崩溃。