Так что я думаю, что схожу с ума.
Я обновился до XCode 4.2, поэтому у меня будет IOS 5 SDK.
У меня есть приложение, которое прекрасно работает дообновление.Теперь у меня странная проблема.Он не работает на моем IOS 5 iPad 2 и не будет работать в симуляторе IOS 5.Прекрасно работает в симуляторе 4.3.
Для целей этого вопроса у меня есть два класса, основанные на UIViewController.Они не используют файлы NIB.Один, под названием HistoryBrowser, прекрасно работает.Другой, NoteBrowseViewController, построенный по тем же линиям, этого не делает.
Из NoteBrowseView.Controller.h:
@interface NoteBrowseViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate, UIActionSheetDelegate, UISearchDisplayDelegate, UITabBarDelegate, MKMapViewDelegate> {
UITableView* tableView;
... buncha other vars ...
}
@property (retain, nonatomic) UITableView* tableView;
... buncha other properties ...
Из NoteBrowseViewController.m:
@synthesize tableView
- (id)initWithEditing:(BOOL)inEditingMode inserting:(BOOL)inserting {
self=[super init];
if (self) {
self.isInserting=inserting;
self.isEditing=inEditingMode;
self.viewIsMap=NO;
self.insertType=defInsertTypeLink;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:0],@"viewSortOrder",
[NSNumber numberWithInt:1],@"priorityView",
[NSNumber numberWithBool:NO],@"simpleView",
nil];
[defaults registerDefaults:appDefaults];
self.viewIsSimple=[[NSUserDefaults standardUserDefaults]boolForKey:@"simpleView"];
}
return self;
}
-(void)loadView {
self.view=[[UIView alloc]initWithFrame:[[UIScreen mainScreen] applicationFrame]];
UIButton* aButton;
UIImage* buttonImage;
UIBarButtonItem* spacer=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UISegmentedControl* sc=[[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObjects:@"Alpha",@"Edit", @"View", nil]];
[sc addTarget:self action:@selector(segmentedControlValueChanged:) forControlEvents:UIControlEventValueChanged];
[sc setWidth:55.0 forSegmentAtIndex:0];
[sc setWidth:55.0 forSegmentAtIndex:1];
[sc setWidth:55.0 forSegmentAtIndex:2];
sc.selectedSegmentIndex=[[NSUserDefaults standardUserDefaults] integerForKey:@"viewSortOrder"];
sc.segmentedControlStyle=UISegmentedControlStyleBar;
UISegmentedControl* prisc=[[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObjects:@"Open",@"All", nil]];
[prisc addTarget:self action:@selector(prioritySegmentedControlValueChanged:) forControlEvents:UIControlEventValueChanged];
[prisc setWidth:55.0 forSegmentAtIndex:0];
[prisc setWidth:55.0 forSegmentAtIndex:1];
prisc.selectedSegmentIndex=[[NSUserDefaults standardUserDefaults] integerForKey:@"priorityView"];
prisc.segmentedControlStyle=UISegmentedControlStyleBar;
UIBarButtonItem* segmentedButton=[[UIBarButtonItem alloc]initWithCustomView:sc];
UIBarButtonItem* prioritySegmentedButton=[[UIBarButtonItem alloc]initWithCustomView:prisc];
buttonImage=[UIImage imageNamed:@"13-plus.png"];
aButton=[UIButton buttonWithType:UIButtonTypeCustom];
[aButton setImage:buttonImage forState:UIControlStateNormal];
aButton.frame=CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
UIBarButtonItem* addButton=[[UIBarButtonItem alloc]initWithCustomView:aButton];
[aButton addTarget:self action:@selector(addButton:) forControlEvents:UIControlEventTouchUpInside];
buttonImage=[UIImage imageNamed:@"187-pencil.png"];
aButton=[UIButton buttonWithType:UIButtonTypeCustom];
[aButton setImage:buttonImage forState:UIControlStateNormal];
aButton.frame=CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
UIBarButtonItem* editButton=[[UIBarButtonItem alloc]initWithCustomView:aButton];
[aButton addTarget:self action:@selector(editButton:) forControlEvents:UIControlEventTouchUpInside];
buttonImage=[UIImage imageNamed:@"21-circle-east.png"];
aButton=[UIButton buttonWithType:UIButtonTypeCustom];
[aButton setImage:buttonImage forState:UIControlStateNormal];
aButton.frame=CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
UIBarButtonItem* simplify=[[UIBarButtonItem alloc]initWithCustomView:aButton];
[aButton addTarget:self action:@selector(simplify:) forControlEvents:UIControlEventTouchUpInside];
buttonImage=[UIImage imageNamed:@"25-circle-west.png"];
aButton=[UIButton buttonWithType:UIButtonTypeCustom];
[aButton setImage:buttonImage forState:UIControlStateNormal];
aButton.frame=CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
UIBarButtonItem* complexify=[[UIBarButtonItem alloc]initWithCustomView:aButton];
[aButton addTarget:self action:@selector(complexify:) forControlEvents:UIControlEventTouchUpInside];
buttonImage=[UIImage imageNamed:@"243-globe.png"];
aButton=[UIButton buttonWithType:UIButtonTypeCustom];
[aButton setImage:buttonImage forState:UIControlStateNormal];
aButton.frame=CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
UIBarButtonItem* map=[[UIBarButtonItem alloc]initWithCustomView:aButton];
[aButton addTarget:self action:@selector(mapify:) forControlEvents:UIControlEventTouchUpInside];
buttonImage=[UIImage imageNamed:@"162-receipt.png"];
aButton=[UIButton buttonWithType:UIButtonTypeCustom];
[aButton setImage:buttonImage forState:UIControlStateNormal];
aButton.frame=CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
UIBarButtonItem* notes=[[UIBarButtonItem alloc]initWithCustomView:aButton];
[aButton addTarget:self action:@selector(showNotes:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem* cancelButton=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(cancelButtonPressed:)];
self.doneToolbar=[NSArray arrayWithObjects:spacer, cancelButton, nil];
self.toolbar=[[[UIToolbar alloc]init]autorelease];
if(self.isEditing) {
self.complexToolbar=[NSArray arrayWithObjects:simplify, spacer, segmentedButton, prioritySegmentedButton, spacer, cancelButton, nil];
self.simpleToolbar=[NSArray arrayWithObjects:complexify, spacer, cancelButton, nil];
}
else {
self.complexToolbar=[NSArray arrayWithObjects:simplify, map, spacer, segmentedButton, prioritySegmentedButton, spacer, addButton, editButton, cancelButton, nil];
self.simpleToolbar=[NSArray arrayWithObjects:complexify, map, spacer, addButton, editButton, cancelButton, nil];
}
self.mapToolbar=[NSArray arrayWithObjects:notes, spacer, prioritySegmentedButton, spacer, cancelButton, nil];
if (self.viewIsSimple) {
[self.toolbar setItems:self.simpleToolbar animated:YES];
}
else {
[self.toolbar setItems:self.complexToolbar animated:YES];
}
self.toolbar.autoresizingMask=UIViewAutoresizingFlexibleWidth;
[self.toolbar sizeToFit];
CGFloat toolbarHeight = [self.toolbar frame].size.height;
CGRect rootViewBounds=self.view.bounds;
CGFloat rootViewHeight = CGRectGetHeight(rootViewBounds);
CGFloat rootViewWidth = CGRectGetWidth(rootViewBounds);
[self.toolbar setFrame:CGRectMake(0,0, rootViewWidth, toolbarHeight)];
self.mapView=[[[MKMapView alloc]initWithFrame:CGRectMake(0, toolbarHeight, rootViewWidth, rootViewHeight-(self.isInserting?49:0)-toolbarHeight)]autorelease];
self.mapView.delegate=self;
self.mapView.zoomEnabled=YES;
self.mapView.scrollEnabled=YES;
self.mapView.autoresizingMask=UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
self.tableView=[[UITableView alloc]initWithFrame:CGRectMake(0, toolbarHeight, rootViewWidth, rootViewHeight-(self.isInserting?49:0)-toolbarHeight)
style:UITableViewStylePlain];
self.tableView.delegate=self;
self.tableView.dataSource=self;
self.tableView.autoresizingMask=UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
self.view.autoresizesSubviews = YES;
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
UISearchBar* searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 44, rootViewWidth, 44.0)];
searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
self.tableView.tableHeaderView = searchBar;
self.searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchDisplayController.delegate = self;
self.searchDisplayController.searchResultsDataSource = self;
self.searchDisplayController.searchResultsDelegate = self;
[self.view addSubview:self.tableView];
[self.view addSubview:self.toolbar];
if (self.isInserting) {
UITabBarItem* item1=[[[UITabBarItem alloc]initWithTitle:@"Link" image:nil tag:defInsertTypeLink]autorelease];
UITabBarItem* item2=[[[UITabBarItem alloc]initWithTitle:@"Contents Later" image:nil tag:defInsertTypeContentsLater]autorelease];
UITabBarItem* item3=[[[UITabBarItem alloc]initWithTitle:@"Contents Now" image:nil tag:defInsertTypeContentsNow]autorelease];
UITabBar* tabbar=[[UITabBar alloc]initWithFrame:CGRectMake(0, rootViewHeight-49, rootViewWidth, 49)];
tabbar.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
[tabbar setDelegate:self];
[tabbar setItems:[NSArray arrayWithObjects:item1, item2, item3, nil] animated:YES];
[tabbar setSelectedItem:item1];
[self.view addSubview:tabbar];
}
if(self.viewIsSimple) {
self.contentSizeForViewInPopover = CGSizeMake(200.0, 625.0);
}
else {
self.contentSizeForViewInPopover = CGSizeMake(450.0, 625.0);
}
self.view.autoresizesSubviews = YES;
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.note=nil;
[sc release];
[prisc release];
[addButton release];
[prioritySegmentedButton release];
[cancelButton release];
[segmentedButton release];
[spacer release];
[editButton release];
[map release];
[simplify release];
[complexify release];
}
И, наконец, экземпляр NoteBrowseViewController создается таким образом из другого контроллера представления:
self.noteBrowseViewController=[[NoteBrowseViewController alloc]initWithEditing:NO inserting:NO];
self.noteBrowseViewController.delegate=self;
self.popoverController = [[UIPopoverController alloc]initWithContentViewController:self.noteBrowseViewController];
self.popoverController.delegate = self;
[self.popoverController presentPopoverFromRect:((UIButton*)sender).frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
Так вот, что происходит.Если я запускаю это в отладке и следую, как только выполнение доходит до этой строки:
CGRect rootViewBounds=self.view.bounds;
Программа аварийно завершает работу со следующими ошибками:
2011-10-20 11:42:02.703 ActionNote3[12332:15803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(0x1eb0052 0x2a60d0a 0x1e9d36e 0x1e9e220 0x1968cb6 0x5153b 0x50e11 0x50879 0x52e4a 0xdcc64e 0x4bcb3 0x72d1 0x1eb1ec9 0xd095c2 0xd0955a 0xdaeb76 0xdaf03f 0xdae2fe 0xd2ea30 0xd2ec56 0xd15384 0xd08aa9 0x20c7fa9 0x1e841c5 0x1de9022 0x1de790a 0x1de6db4 0x1de6ccb 0x20c6879 0x20c693e 0xd06a9b 0x2dbd 0x2d35)
terminate called throwing an exception
При просмотре событий во времяотладка, я знаю, что self.view настраивается правильно, и этот loadView вызывается, когда это должно быть.И не эта строка делает его неудачным - это все, что относится к self.view!что ???
Что действительно сводит меня с ума, так это то, что у меня есть другой контроллер подклассов, HistoryBrowser, который загружается точно таким же образом ... и он отлично работает.
Итак,Помимо того, что я расстроен, что я не могу понять это, я хотел бы понять:
- Что изменилось в XCode 4.2 (из 4.1), что может вызвать это, или это проблема IOS 5?
- Что означает эта ошибка, и что я могу с ней сделать?
РЕДАКТИРОВАТЬ:
Таким образом, на основе предложений из ответа Abberantниже, я:
- изменил initwithnib просто на init
- удалил метод loadView
- добавил полное сообщение об ошибке
- добавил более актуальноекод метода init
И теперь ссылка на self.view работает правильно.Но вещи только что стали незнакомыми.
Выполнение проходит без первой ссылки на self.view без ошибок.Однако теперь он останавливается на:
self.tableView.tableHeaderView = searchBar;
в методе init.
Полученное сообщение об ошибке очень похоже на то, которое я получал раньше:
2011-10-20 12:34:04.818 ActionNote3[13487:15803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(0x1eaf052 0x2a5fd0a 0x1e9c36e 0x1e9d220 0x1967cb6 0x50b4b 0x50421 0x4fe89 0x4d757 0x6641 0x1eb0ec9 0xd085c2 0xd0855a 0xdadb76 0xdae03f 0xdad2fe 0xd2da30 0xd2dc56 0xd14384 0xd07aa9 0x20c6fa9 0x1e831c5 0x1de8022 0x1de690a 0x1de5db4 0x1de5ccb 0x20c5879 0x20c593e 0xd05a9b 0x212d 0x20a5)
terminate called throwing an exception
Итак, если я закомментирую эту строку, выполнение продолжается до тех пор, пока не достигнет этой группы строк, где происходит сбой при попытке выполнить executeFetch.
NSError *error = nil;
if (![[self currentFetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
Отладка в код для показа [self currentFetchedResultsController]что контроллер выбранных результатов настраивается правильно и без проблем.
Полученная здесь ошибка такая же, как и выше.Числа в первом стеке вызовов вызовов меняются, но в остальном ошибка та же.
Так что я остаюсь, думая, что у меня здесь возникает большая проблема.Я просто не знаю, как отследить это.Как я сказал где-то там, у меня есть другое представление, сконструированное таким же образом, которое прекрасно загружается.
Редактировать:
Так что NJones в своем ответе ниже предложилследуя рекомендациям Apple, поместив соответствующий код в loadView и viewDidLoad.Так я и сделал.Я переместил всю конструкцию представления из init в loadView и запустил fetchedResultsController в viewDidLoad.
Приложение по-прежнему падает на том же месте:
self.tableView.tableHeaderView = searchBar
С той же ошибкой, что и отмеченнаявыше.
Спасибо!