我想将用户输入的文本发送到SearchViewController中的itemSearch
UITextField
到MatchCenterViewController,以便它可以在函数中使用它。
我通过将其IBOutlet放在SearchViewController的标头中,使itemSearch
属性公开。然而,在segue期间似乎没有成功发送,因为eBayMatchCenterSearch
函数在ShowMatchCenterSegue
期间运行时崩溃。
错误讯息:
2014-05-21 15:47:17.785 Parse+Storyboard[8787:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]'
*** First throw call stack:
(
0 CoreFoundation 0x02a881e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x026468e5 objc_exception_throw + 44
2 CoreFoundation 0x02a4e376 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 390
3 CoreFoundation 0x02a7bc29 +[NSDictionary dictionaryWithObjects:forKeys:count:] + 73
4 Parse+Storyboard 0x00004c09 -[MatchCenterViewController viewDidLoad] + 329
5 UIKit 0x0142533d -[UIViewController loadViewIfRequired] + 696
6 UIKit 0x014255d9 -[UIViewController view] + 35
7 UIKit 0x0143f942 -[UINavigationController _startCustomTransition:] + 778
8 UIKit 0x0144c8f7 -[UINavigationController _startDeferredTransitionIfNeeded:] + 688
9 UIKit 0x0144d4e9 -[UINavigationController __viewWillLayoutSubviews] + 57
10 UIKit 0x0158e0d1 -[UILayoutContainerView layoutSubviews] + 213
11 UIKit 0x01375964 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
12 libobjc.A.dylib 0x0265882b -[NSObject performSelector:withObject:] + 70
13 QuartzCore 0x0064b45a -[CALayer layoutSublayers] + 148
14 QuartzCore 0x0063f244 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
15 QuartzCore 0x0063f0b0 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
16 QuartzCore 0x005a57fa _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
17 QuartzCore 0x005a6b85 _ZN2CA11Transaction6commitEv + 393
18 QuartzCore 0x005a7258 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
19 CoreFoundation 0x02a5036e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
20 CoreFoundation 0x02a502bf __CFRunLoopDoObservers + 399
21 CoreFoundation 0x02a2e254 __CFRunLoopRun + 1076
22 CoreFoundation 0x02a2d9d3 CFRunLoopRunSpecific + 467
23 CoreFoundation 0x02a2d7eb CFRunLoopRunInMode + 123
24 GraphicsServices 0x02ce55ee GSEventRunModal + 192
25 GraphicsServices 0x02ce542b GSEventRun + 104
26 UIKit 0x01306f9b UIApplicationMain + 1225
27 Parse+Storyboard 0x00002b0d main + 141
28 libdyld.dylib 0x038e2701 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
SearchViewController.h:
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import <Parse/PFCloud.h>
#import "CriteriaViewController.h"
@interface SearchViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIButton *nextButtonOutlet;
@property (nonatomic, copy) NSString *topCategory1;
@property (nonatomic, copy) NSString *topCategory2;
@property (nonatomic, copy) NSNumber *topCategoryId1;
@property (nonatomic, copy) NSNumber *topCategoryId2;
@property (weak, nonatomic) IBOutlet UITextField *itemSearch;
@end
SearchViewController.m:
#import "SearchViewController.h"
#import "MatchCenterViewController.h"
#import "SearchCategoryChooserViewController.h"
@interface SearchViewController ()
@property (weak, nonatomic) IBOutlet UIButton *nextButton;
@end
@implementation SearchViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.nextButtonOutlet addTarget:self action:@selector(nextButton:) forControlEvents:UIControlEventTouchUpInside];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)nextButton:(id)sender
{
if (self.itemSearch.text.length > 0) {
[PFCloud callFunctionInBackground:@"eBayCategorySearch"
withParameters:@{@"item": self.itemSearch.text}
block:^(NSDictionary *result, NSError *error) {
NSLog(@"'%@'", result);
// Parses results
NSArray *resultArray = [result objectForKey:@"results"];
// Number of Top Categories
NSDictionary *dictionary0 = [resultArray objectAtIndex:0];
NSNumber *numberOfTopCategories = [dictionary0 objectForKey:@"Number of top categories"];
// Ids of the Top Categories
NSDictionary *dictionary1 = [resultArray objectAtIndex:1];
NSArray *topCategoryIdsArray = [dictionary1 objectForKey:@"Top category Ids"];
// Names of the Top Categories
NSDictionary *dictionary2 = [resultArray objectAtIndex:2];
NSArray *topCategoryNamesArray = [dictionary2 objectForKey:@"Top category names"];
// Number of Top Categories matching User Categories
NSDictionary *dictionary3 = [resultArray objectAtIndex:3];
NSNumber *numberOfMatches = [dictionary3 objectForKey:@"Number of matches"];
// Names of Top Categories matching User Categories
NSDictionary *dictionary4 = [resultArray objectAtIndex:4];
NSArray *userCategoriesThatMatchSearch = [dictionary4 objectForKey:@"User categories that match search"];
// Defines where each topCategory name will come from
self.topCategory1 = [topCategoryNamesArray objectAtIndex:0];
if ([numberOfTopCategories intValue] == 2) {
self.topCategory2 = [topCategoryNamesArray objectAtIndex:1];
}
// Defines where each topCategory ID will come from
self.topCategoryId1 = [topCategoryIdsArray objectAtIndex:0];
if ([numberOfTopCategories intValue] == 2) {
self.topCategoryId2 = [topCategoryIdsArray objectAtIndex:1];
}
if (!error) {
// Decides which segue is taken based on results
// if 1 match found clear categoryResults and top2 array
if ([numberOfMatches intValue] == 1 ){
[self performSegueWithIdentifier:@"ShowMatchCenterSegue" sender:self];
}
// if 2 matches found
else if ([numberOfMatches intValue] == 2){
[self performSegueWithIdentifier:@"ShowUserCategoryChooserSegue" sender:self];
//default to selected categories criteria -> send to matchcenter -> clear categoryResults and top2 array
}
// if no matches found, and 1 top category is returned
else if ([numberOfMatches intValue] == 0 && [numberOfTopCategories intValue] == 1) {
[self performSegueWithIdentifier:@"ShowCriteriaSegue" sender:self];
}
// if no matches are found, and 2 top categories are returned
else if ([numberOfMatches intValue] == 0 && [numberOfTopCategories intValue] == 2) {
[self performSegueWithIdentifier:@"ShowSearchCategoryChooserSegue" sender:self];
}
}
}];
}
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"ShowMatchCenterSegue"]) {
MatchCenterViewController *controller = (MatchCenterViewController *) segue.destinationViewController;
// Send over the search query
controller.itemSearch.text = self.itemSearch.text;
}
else if([segue.identifier isEqualToString:@"ShowSearchCategoryChooserSegue"]){
SearchCategoryChooserViewController *controller = (SearchCategoryChooserViewController *) segue.destinationViewController;
// Send over the search query as well as both categories to the Category Chooser VC
controller.itemSearch.text = self.itemSearch.text;
controller.topCategory1 = self.topCategory1;
controller.topCategory2 = self.topCategory2;
controller.topCategoryId1 = self.topCategoryId1;
controller.topCategoryId2 = self.topCategoryId2;
}
else if([segue.identifier isEqualToString:@"ShowCriteriaSegue"]){
CriteriaViewController *controller = (CriteriaViewController *) segue.destinationViewController;
// Send over the search query as well as the specific category to CriteriaVC to use
controller.itemSearch = self.itemSearch.text;
controller.chosenCategory = self.topCategoryId1;
}
}
@end
MatchCenterViewController.h:
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import "AsyncImageView.h"
#import "SearchViewController.h"
@interface MatchCenterViewController : UIViewController <UITableViewDataSource>
@property (nonatomic) IBOutlet UITextField *itemSearch;
@property (nonatomic, strong) NSArray *imageURLs;
@end
MatchCenterViewController.m:
#import "MatchCenterViewController.h"
#import <UIKit/UIKit.h>
@interface MatchCenterViewController () <UITableViewDataSource, UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *matchCenter;
@property (strong, nonatomic) NSArray *itemsArray;
@end
@implementation MatchCenterViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//perform search with criteria just submitted
[PFCloud callFunctionInBackground:@"eBayMatchCenterSearch"
withParameters:@{@"item": self.itemSearch.text,
@"minPrice": @"250",
@"maxPrice": @"400",
@"itemCondition": @"New",
// @"itemLocation": @"US",
}
block:^(NSString *result, NSError *error) {
if (!error) {
NSLog(@"The result is '%@'", result);
}
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
答案 0 :(得分:4)
itemSearch
是IBOutlet
,因此在视图加载之前不会实例化。在prepareForSegue
中设置其文本值意味着您要设置nil
的文本值。
在目标控制器中创建NSString
属性,并在segue期间设置该属性。然后将其复制到itemSearch.text
中的viewDidLoad
。