<<精通iOS开发>>第14章例子代码小缺陷的修复

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.
如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;)


首先推荐大家看这本书,整本书逻辑非常清晰,代码如何从无到有,到丰满说的很有条理.

说实话本书到目前为止错误还是极少的,不过人无完人,在第14章前半部分项目的代码中,作者在MasterVC到DetailVC中又直接添加了一个segue,该segue的ID为”masterToDetail”,作用是当新建一个tinyPix文档时可以直接跳转到DetailVC来编辑文档.

作者同样意识到如果直接从MasterVC的表视图cell直接转到DetailVC时也需要做一些额外的操作,该操作的作用是,当用户点击已存在的tinyPix时跳转到DetailVC中打开已存在的文档.

作者是这样修改prepareForSegue::方法的:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if (sender == self) {
        UIViewController *destination = segue.destinationViewController;
        if ([destination respondsToSelector:@selector(setDetailItem:)]) {
            [destination setValue:_chosenDoc forKey:@"detailItem"];
        }
    }else{
        NSIndexPath *indexPath = self.tableView.indexPathForSelectedRow;
        NSString *filename = _docFilenames[indexPath.row];
        NSURL *docUrl = [self urlForFilename:filename];
        _chosenDoc = [[HyTinyPixDocument alloc]initWithFileURL:docUrl];
        [_chosenDoc openWithCompletionHandler:^(BOOL success){
            if (success) {
                UIViewController *destination = segue.destinationViewController;
                if ([destination respondsToSelector:@selector(setDetailItem:)]) {
                    [destination setValue:_chosenDoc forKey:@"detailItem"];
                }
            }else{
                NSLog(@"failed to load!");
            }
        }];
    }
}

但是实际执行App时发现点击已存在的tinyPix文件并不能正确在DetailVC中显示文档的内容.在上述方法的else分支后下断点,发现由TableViewCell跳转而来的代码其segue.destinationViewController并不是我们希望的DetailViewController,而是UINavigationController.而后者自然不存在神马setDetailItem:方法.

我不知道这是作者的笔误还是什么其他原因,或者是新版的Xcode中Master-Detail Application模板发生了变化?但至少在Xcode7.2中情况是这样.

那么如何修复这个问题呢?其实比你想象的要简单,修改如下:

if (success) {
                //UIViewController *destination = segue.destinationViewController;
                DetailViewController *detailVC = (DetailViewController*)[
                                        segue.destinationViewController topViewController];
                if ([detailVC respondsToSelector:@selector(setDetailItem:)]) {
                    [detailVC setValue:_chosenDoc forKey:@"detailItem"];
                }
            }else{
                NSLog(@"failed to load!");
            }

在这里我们需要的是destinationVC的topViewController对象,而不是destinationVC本身.

编译连接App,现在两种方法进入到DetailVC都表现正常了:

<<精通iOS开发>>第14章例子代码小缺陷的修复