iOS 滑出菜单导致应用程序崩溃。怎么修?
Posted
技术标签:
【中文标题】iOS 滑出菜单导致应用程序崩溃。怎么修?【英文标题】:iOS Slide out menu is causing app to crash. How to fix? 【发布时间】:2014-04-06 00:28:36 【问题描述】:我正在创建一个带有滑出导航栏的 RSS 提要应用程序,如图所示 (http://www.appcoda.com/ios-programming-sidebar-navigation-menu/)。 该应用程序将加载,RSS 提要将解析并出现在我的主屏幕上。您可以单击一个提要,它将导致一个 webView 显示相应的网站。我还将在左上角有一个导航栏按钮来切换滑出菜单。我无法继续处理我的应用程序,因为它一直在崩溃。顺便说一句,我正在使用名为 SWRevealViewController 的第三方库。这是我的 MasterViewController:
//
// JSSMasterViewController.m
// News App
//
// Created by Steve on 4/5/14.
// Copyright (c) 2014 self.edu.steve. All rights reserved.
//
#import "JSSMasterViewController.h"
#import "JSSDetailViewController.h"
#import "SWRevealViewController.h"
@interface JSSMasterViewController ()
NSXMLParser *parser;
NSMutableArray *feeds;
NSMutableDictionary *item;
NSMutableString *title;
NSMutableString *link;
NSString *element;
@end
@implementation JSSMasterViewController
- (void)awakeFromNib
[super awakeFromNib];
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
feeds = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:@"http://images.apple.com/main/rss/hotnews/hotnews.rss"];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
// Change button color
_sidebarButton.tintColor = [UIColor colorWithWhite:0.96f alpha:0.2f];
// Set the side bar button action. When it's tapped, it'll show up the sidebar.
_sidebarButton.target = self.revealViewController;
_sidebarButton.action = @selector(revealToggle:);
// Set the gesture
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return 1;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return feeds.count;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
cell.textLabel.text = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
return cell;
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
element = elementName;
if ([element isEqualToString:@"item"])
item = [[NSMutableDictionary alloc] init];
title = [[NSMutableString alloc] init];
link = [[NSMutableString alloc] init];
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
if ([elementName isEqualToString:@"item"])
[item setObject:title forKey:@"title"];
[item setObject:link forKey:@"link"];
[feeds addObject:[item copy]];
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
if ([element isEqualToString:@"title"])
[title appendString:string];
else if ([element isEqualToString:@"link"])
[link appendString:string];
- (void)parserDidEndDocument:(NSXMLParser *)parser
[self.tableView reloadData];
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([[segue identifier] isEqualToString:@"showDetail"])
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *string = [feeds[indexPath.row] objectForKey: @"link"];
[[segue destinationViewController] setUrl:string];
@end
这是管理滑出菜单的 SideBar View 控制器:
//
// JSSSidebarViewController.m
// News App
//
// Created by Steve on 4/5/14.
// Copyright (c) 2014 self.edu.steve. All rights reserved.
//
#import "JSSSidebarViewController.h"
#import "SWRevealViewController.h"
@interface JSSSidebarViewController ()
@end
@implementation JSSSidebarViewController
NSArray *menuItems;
- (id)initWithStyle:(UITableViewStyle)style
self = [super initWithStyle:style];
if (self)
// Custom initialization
return self;
- (void)viewDidLoad
[super viewDidLoad];
menuItems = @[@"title", @"news", @"comments", @"map", @"calendar", @"wishlist", @"bookmark", @"tag"];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
// Return the number of sections.
return 1;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
// Return the number of rows in the section.
return [menuItems count];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
- (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
// Set the title of navigation bar by using the menu items
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
destViewController.title = [[menuItems objectAtIndex:indexPath.row] capitalizedString];
// Set the photo if it navigates to the PhotoView
if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] )
SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;
swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc)
UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
[navController setViewControllers: @[dvc] animated: NO ];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
;
@end
我无法找到解决方案。这是我的日志:
2014-04-05 20:17:43.843 News App[4496:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(
0 CoreFoundation 0x0000000101968495 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001016c799e objc_exception_throw + 43
2 CoreFoundation 0x000000010191f374 -[__NSArrayM insertObject:atIndex:] + 820
3 UIKit 0x00000001002d40da -[UIView(UIViewGestures) addGestureRecognizer:] + 199
4 News App 0x0000000100001ecf -[JSSMasterViewController viewDidLoad] + 719
5 UIKit 0x000000010036a59e -[UIViewController loadViewIfRequired] + 562
6 UIKit 0x000000010036a777 -[UIViewController view] + 29
7 UIKit 0x00000001006752e2 -[UIClientRotationContext initWithClient:toOrientation:duration:andWindow:] + 390
8 UIKit 0x00000001002b0ffa -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 1109
9 UIKit 0x00000001002b0b9f -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 36
10 UIKit 0x00000001002b0aef -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 101
11 UIKit 0x00000001002afdfe -[UIWindow _updateToInterfaceOrientation:duration:force:] + 377
12 UIKit 0x000000010036e70a -[UIViewController _tryBecomeRootViewControllerInWindow:] + 147
13 UIKit 0x00000001002aab1b -[UIWindow addRootViewControllerViewIfPossible] + 490
14 UIKit 0x00000001002aac70 -[UIWindow _setHidden:forced:] + 282
15 UIKit 0x00000001002b3ffa -[UIWindow makeKeyAndVisible] + 51
16 UIKit 0x000000010026fc98 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1788
17 UIKit 0x0000000100273a0c -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 660
18 UIKit 0x0000000100284d4c -[UIApplication handleEvent:withNewEvent:] + 3189
19 UIKit 0x0000000100285216 -[UIApplication sendEvent:] + 79
20 UIKit 0x0000000100275086 _UIApplicationHandleEvent + 578
21 GraphicsServices 0x0000000103ae171a _PurpleEventCallback + 762
22 GraphicsServices 0x0000000103ae11e1 PurpleEventCallback + 35
23 CoreFoundation 0x00000001018ea679 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
24 CoreFoundation 0x00000001018ea44e __CFRunLoopDoSource1 + 478
25 CoreFoundation 0x0000000101913903 __CFRunLoopRun + 1939
26 CoreFoundation 0x0000000101912d83 CFRunLoopRunSpecific + 467
27 UIKit 0x00000001002732e1 -[UIApplication _run] + 609
28 UIKit 0x0000000100274e33 UIApplicationMain + 1010
29 News App 0x0000000100002c23 main + 115
30 libdyld.dylib 0x00000001020005fd start + 1
31 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
感谢您的帮助!
【问题讨论】:
【参考方案1】:错误正是您的错误日志所说的:
'*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
您正试图将一个对象插入到一个数组中,而该对象为 nil。在这种特殊情况下,正是这一行导致了问题:
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
您需要先分配self.revealViewController.panGestureRecognizer
,然后再将其添加为视图的手势识别器。
一种分配手势识别器的方法:
UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(someMethod:)];
[self.view addGestureRecognizer:gestureRecognizer];
【讨论】:
您对错误是正确的。你能告诉我如何分配 self.revealViewController.panGestureRecognizer 以及在哪里分配它。我不知道语法。谢谢,我是 iOS 新手。 @Enrico Susatyo 非常感谢!我不再收到该错误,但不断出现新错误。这显示在我的日志 '2014-04-08 20:07:31.101 News App[10272:60b] -[JSSMasterViewControllerrevealToggle:]: unrecognized selector sent to instance 0x1093766b0' 我不明白为什么它不能识别手势。我应该从以前的代码中删除吗?如果是这样,请告诉我。谢谢! @Enrico Susatyo 这听起来像是一个完全不同的问题,它告诉你没有revealToggle这样的方法。您可能希望将此答案标记为有用/正确,然后如果您仍然不确定,请提出另一个问题。 好的!非常感谢您的参与! @Enrico Susatyo以上是关于iOS 滑出菜单导致应用程序崩溃。怎么修?的主要内容,如果未能解决你的问题,请参考以下文章
在 iOS14 上释放 wkwebview 时,发送手势事件导致崩溃