gpt4 book ai didi

objective-c - 如果我在从委托(delegate)访问我的 View 时得到 EXC_BAD_ACCESS,这是否意味着我有内存泄漏?

转载 作者:行者123 更新时间:2023-12-01 18:02:04 24 4
gpt4 key购买 nike

我有一个像这样初始化的对象:

pdtd = [[ProfileDataTableDelegate alloc] initWithTableView:profileDataTableView scrollView:contentScrollView];

所以我的 view传递给 pdtd目的。我现在可以毫无问题地注销我的 View 。当我在文本字段内单击并告知 ScrollView 重新定位时,我收到错误消息。在我的表委托(delegate)(pdtd)上,我得到了这个函数第一行中给我“EXC_BAD_ACCESS”的错误:
- (void)keyboardDidShow:(NSNotification *)notif {
[self.scrollView setContentOffset:CGPointMake(0, 100) animated:YES]; // <-- ERROR SHOWS UP HERE

[self.scrollView setContentSize:CGSizeMake([self.scrollView frame].size.width,
[self.scrollView frame].size.height + 100)];
}

这很奇怪,因为我在另一个 View 上这样做并且效果很好。我不确定出了什么问题或如何从调试器中获取更多信息。以下是相关类的相关功能。

ProfileViewController.h
...

#import "ProfileDataTableDelegate.h"


@interface ProfileViewController : UIViewController <UINavigationControllerDelegate> {
UITableView *profileDataTableView;
ProfileDataTableDelegate *pdtd;
UINavigationBar *navBar;
UIScrollView *contentScrollView;
}

...

@property (nonatomic, retain) IBOutlet UITableView *profileDataTableView;
@property (nonatomic, retain) ProfileDataTableDelegate *pdtd;
@property (nonatomic, retain) IBOutlet UINavigationBar *navBar;
@property (nonatomic, retain) IBOutlet UIScrollView *contentScrollView;

@end

ProfileViewController.m
...

- (void)viewDidLoad {
[super viewDidLoad];

//nav title
[navBar.topItem setTitle:@"Your Profile"];

[self.navigationController setNavigationBarHidden:NO];

// nav bar button
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(saveBtnTouched:)];
saveButton.enabled = false;
[navBar.topItem setRightBarButtonItem:saveButton];

pdtd = [[ProfileDataTableDelegate alloc] initWithTableView:profileDataTableView scrollView:contentScrollView];

void (^block)(BOOL) = ^(BOOL is_valid) {
if(is_valid == YES) {
[saveButton setEnabled:YES];
} else if(is_valid == NO) {
[saveButton setEnabled:NO];
}
};

[pdtd setValidatorBlock:block];
}

...

ProfileDateTableDelegate.h
...

#import "ValidatedTextViewTableCell.h"

typedef void (^ ValidatorBlock)(BOOL);

@interface ProfileDataTableDelegate : NSObject <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate> {
UITableView *profileDataTableView;
UIScrollView *scrollView;

...
}

- (id)initWithTableView:(UITableView *)tableView scrollView:(UIScrollView *)scrollView;

...

@property (nonatomic, retain) IBOutlet UITableView *profileDataTableView;
@property (nonatomic, retain) UIScrollView *scrollView;

@end

ProfileDateTableDelegate.m
...

@implementation ProfileDataTableDelegate

@synthesize profileDataTableView;
@synthesize profileDataTableLabels;
@synthesize scrollView;

@synthesize emailCell, phoneCell, nameCell;
@synthesize validatedTextViewTableCell;
@synthesize validatorBlock;


- (id)initWithTableView:(UITableView *)tableView scrollView:(UIScrollView *)view {
self = [super init];

if(self) {
profileDataTableView = tableView;
[profileDataTableView setDelegate:self];
[profileDataTableView setDataSource:self];

scrollView = view;

profileDataTableLabels = [[NSArray alloc] initWithObjects:@"Name", @"Email", @"Phone", nil];

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector (keyboardDidShow:)
name: UIKeyboardDidShowNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector (keyboardDidHide:)
name: UIKeyboardDidHideNotification object:nil];
}

return self;
}

...

- (void)keyboardDidShow:(NSNotification *)notif {
//NSLog(@"keyboard did show %@", notif); // notif gives coordinates etc
//[scrollView setContentOffset:CGPointMake(0, 480 - 372) animated:YES];

[self.scrollView setContentOffset:CGPointMake(0, 100) animated:YES];

[self.scrollView setContentSize:CGSizeMake([self.scrollView frame].size.width,
[self.scrollView frame].size.height + 100)];

//[scrollView setFrame:CGRectMake(0, 0, 320, 320)];


// disable scrolling because it resets the rect position
//[scrollView setScrollEnabled:NO];
}

...

@end

我不确定如何获取堆栈跟踪信息(Xcode 4.2)。此外,在分析中有几个警告,但没有什么严重的(例如蓝色)。

最佳答案

您需要调用self.scrollView = viewscrollView = [view retain]在您的 initWithTableView: ProfileDateTableDelegate.m 中的方法.

基本上发生的情况是,您的 scrollView 在您能够访问它之前已在其他 View 中被释放,因为您的“委托(delegate)”类不会以任何方式保留它,即使您已指定 nonatomic,retain。在您的属性(property)上。由于您直接在 init 中设置 ivar而不是使用 setter 属性,而不是在其上调用保留。直接使用ivar时,必须调用retain如果你想保留它,你自己。

避免此错误的一种方法是使用下划线 _在您的 ivar 之前或之后(Apple 使用 before,所以我使用 after 以避免私有(private) ivar 冲突),如下所示:

在.h中:

@interface{
UIScrollView *scrollView_;
}

@property (nonatomic,retain) UIScrollView *scrollView;

在 *.m 中:
@synthesize scrollView = scrollView_;

那么,你在 init ,您可以像这样保留进来的 View :
scrollView_ = [view retain];

只需确保在 dealloc 中正确释放它即可:
- (void)dealloc{
[scrollView_ release], scrollView_ = nil;
[super dealloc];
}

你可以找到更多关于这一切的信息 here .

关于objective-c - 如果我在从委托(delegate)访问我的 View 时得到 EXC_BAD_ACCESS,这是否意味着我有内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8097324/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com