我有一个像 init 这样的对象:
pdtd = [[ProfileDataTableDelegate alloc] initWithTableView:profileDataTableView scrollView:contentScrollView];
所以我的view
被传递给pdtd
对象。我可以在此时记录我的视图,没有任何问题。当我在文本字段中单击并且滚动视图被告知要重新定位时,我得到错误。在我的表委托(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)];
}
这很奇怪,因为我在另一个视图上执行此操作并且工作正常。我不确定错误或如何从调试器获取更多信息。以下是相关类的相关函数。
...
#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
...
- (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];
}
...
...
#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
...
@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)。此外,在分析时有几个警告,但没有什么严重的(例如蓝色)。
答案 0 :(得分:4)
您需要在self.scrollView = view
的{{1}}方法中致电scrollView = [view retain]
或initWithTableView:
。
基本上发生的事情是,在您能够访问之前,您的scrollView正在其他视图中发布,因为您的“委托”类不会以任何方式保留它,即使您已指定ProfileDateTableDelegate.m
你的财产。由于您直接在nonatomic,retain
中设置ivar而不是使用setter属性,因此不会在其上调用retain。直接使用ivar时,如果要保留,请自行致电init
。
避免此错误的一种方法是在你的ivars之前或之后使用下划线retain
(Apple之前使用,所以我用它来避免私人的ivar碰撞),如下所示:
在.h:
_
in * .m:
@interface{
UIScrollView *scrollView_;
}
@property (nonatomic,retain) UIScrollView *scrollView;
然后,你在@synthesize scrollView = scrollView_;
,你可以像这样保留视图:
init
请确保在scrollView_ = [view retain];
中正确发布:
dealloc
您可以找到有关所有这些here的更多信息。
答案 1 :(得分:1)
EXC_BAD_ACCESS
。没有完成所有代码,这里有一个提示,可以让你立即开始。运行分析器。然后,使用Instruments中的Leaks工具。
有关详细信息,以及导致这些错误的原因的详尽链接以及如何修复的分步说明,请查看这些问题的答案: