UIViewController弹出时EXC_BAD_ACCES问题

发布于 2024-10-13 18:23:48 字数 4822 浏览 2 评论 0原文

我正在尝试创建一个视图控制器,其中包含一个表视图,其中包含可编辑的自定义 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 实现的代码:

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

我知道我没有通知我的委托该视图将会或确实消失,并且我不会填充 UITableView,但现在没有必要实现它。

如果有人能帮助我解决这个问题,我会非常高兴。先感谢您, IEF2

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月静好 2024-10-20 18:23:48

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文