• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

objective-c - 两个 UIViewController 的故事

[复制链接]
菜鸟教程小白 发表于 2022-12-11 20:22:33 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

所以我觉得我快疯了。

我已经更新到 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)initWithEditingBOOL)inEditingMode insertingBOOL)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 actionselector(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 actionselector(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 actionselector(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 从另一个 View Controller 实例化:

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 相关的东西!什么???

真正让我抓狂的是,我还有另一个子类 View Controller HistoryBrowser,它以完全相同的方式加载......而且它工作正常。

所以,除了对我无法弄清楚这一点感到沮丧之外,我想了解一下:

  1. XCode 4.2(从 4.1 开始)中会导致这种情况发生的变化,或者是 这是IOS 5的问题?
  2. 这个错误是什么意思,我该怎么办 关于它?

编辑:

因此,根据 Abberant 以下回答的建议,我:

  1. 将 initwithnib 更改为 init
  2. 删除了 loadView 方法
  3. 添加了完整的错误消息
  4. 在 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

因此,如果我注释掉该行,执行将继续进行,直到它到达这组行,当它尝试执行 performFetch 时它会失败。

    NSError *error = nil;
    if (![[self currentFetchedResultsController] performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

调试 [self currentFetchedResultsController] 的代码表明获取的结果 Controller 设置正确且没有问题。

这里收到的错误和上面一样。第一次 throw 调用堆栈中的数字发生变化,否则错误相同。

所以我想我这里有一个更大的问题。我只是不知道如何追踪它。正如我在某处所说的那样,我有另一个 View ,以相同的方式构建,加载良好。

编辑:

因此,NJones 在下面的回答中建议遵循 Apple 的指导方针,将适当的代码放在 loadView 和 viewDidLoad 中。所以我做了。我将所有 View 构造从 init 移到 loadView 中,并在 viewDidLoad 中启动了 fetchedResultsController。

应用仍然在同一个地方崩溃:

self.tableView.tableHeaderView = searchBar

出现与上述相同的错误。

谢谢!



Best Answer-推荐答案


我会说你应该使用苹果建议的加载模型。这是创建新 UIViewController 子类时在 xCode 中生成的一些代码(为适应而删节):

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
-(void)loadView{
}
*/

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
-(void)viewDidLoad{
    [super viewDidLoad];
}
*/

基于此,由于您是以编程方式创建 View ,我想说您的 init 方法中的大部分内容都属于 loadView 方法。

关于objective-c - 两个 UIViewController 的故事,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7830502/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap