【问题标题】:UIViewController EXC_BAD_ACCES problem when popping弹出时 UIViewController EXC_BAD_ACCES 问题
【发布时间】:2011-06-13 19:16:57
【问题描述】:

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

#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

实现

#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

【问题讨论】:

  • @lef2 你到底为什么要在-dealloc 中向你的ivars 发送retain 消息?你肯定是想发送release 消息。
  • 你推送viewController的代码在哪里?你是让导航控制器自动弹出它还是你自己处理?
  • @Jacob Relkin:你说得对,我的意思是发送发布消息,代码已编辑。
  • @aqua:在用initWithStrings:delegate: 创建它后,我用pushViewController:animated: 显示它。我让导航控制器在没有我自己交互的情况下弹出它。我唯一要做的就是在字符串编辑器通知它确实消失时从委托中释放它。按下后我不会立即松开控制器。

标签: ios uiviewcontroller uinavigationcontroller exc-bad-access


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多