2014-05-21 68 views
0

我想將用戶輸入的文本發送到SearchViewController中的itemSearchUITextField轉換爲MatchCenterViewController,以便它可以在函數中使用它。從一個ViewController向另一個ViewController發送文本時,iOS應用程序崩潰

我已將itemSearch屬性公開,將其IBOutlet放置在SearchViewController的標題中。然而,在segue期間,它似乎沒有成功發送,因爲在ShowMatchCenterSegue期間eBayMatchCenterSearch函數運行時它崩潰。

錯誤消息:

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

你可以在'controller.itemSearch.text = self.itemSearch.text;'之前記錄'itemSearch.text'的值嗎? – lucianomarisi

+0

剛剛做了,它正確地記錄了輸入的內容。 – Ghobs

+0

在MatchCenterViewController中的[[PFCloud callFunctionInBackground:@「eBayMatchCenterSearch」]之前記錄它,但是會給我一個值爲null的值。 – Ghobs

回答

4

itemSearchIBOutlet,因此不會被實例化,直到視圖負載。在prepareForSegue中設置其文本值意味着您將文本值設置爲nil

在您的目的地控制器中創建一個NSString屬性,並在segue期間設置該屬性。然後將其複製到viewDidLoad中的itemSearch.text

相關問題