'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[3]'

ios, objective-c, uitextfield

Solution

One of your properties — it looks like `itemCondition` — is apparently nil. This may be because your properties are weak, so the variable is getting nulled out before you get a chance to look at it, or it may be because your selected segment isn't one of the values you're testing for and thus the variable is nnever set. I can't understand why those string properties are weak, and I strongly suspect they shouldn't be.

Problem

I have two `UITextField`s in my storyboard that are meant to take in a number that the user inputs, a minPrice and maxPrice. When I click submit in the simulator, the app crashes and I receive the following error: ``` Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[3]' *** 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 0x0000b5b5 -[CriteriaViewController submitButton:] + 757 5 libobjc.A.dylib 0x02658880 -[NSObject performSelector:withObject:withObject:] + 77 6 UIKit 0x013083b9 -[UIApplication sendAction:to:from:forEvent:] + 108 7 UIKit 0x01308345 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61 8 UIKit 0x01409bd1 -[UIControl sendAction:to:forEvent:] + 66 9 UIKit 0x01409fc6 -[UIControl _sendActionsForEvents:withEvent:] + 577 10 UIKit 0x01409243 -[UIControl touchesEnded:withEvent:] + 641 11 UIKit 0x01347ddd -[UIWindow _sendTouchesForEvent:] + 852 12 UIKit 0x013489d1 -[UIWindow sendEvent:] + 1117 13 UIKit 0x0131a5f2 -[UIApplication sendEvent:] + 242 14 UIKit 0x01304353 _UIApplicationHandleEventQueue + 11455 15 CoreFoundation 0x02a1177f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15 16 CoreFoundation 0x02a1110b __CFRunLoopDoSources0 + 235 17 CoreFoundation 0x02a2e1ae __CFRunLoopRun + 910 18 CoreFoundation 0x02a2d9d3 CFRunLoopRunSpecific + 467 19 CoreFoundation 0x02a2d7eb CFRunLoopRunInMode + 123 20 GraphicsServices 0x02ce55ee GSEventRunModal + 192 21 GraphicsServices 0x02ce542b GSEventRun + 104 22 UIKit 0x01306f9b UIApplicationMain + 1225 23 Parse+Storyboard 0x000020ed main + 141 24 libdyld.dylib 0x038e2701 start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb) ``` CriteriaViewController.h: ``` #import <UIKit/UIKit.h> #import <Parse/Parse.h> #import "SearchViewController.h" @interface CriteriaViewController : UIViewController{ IBOutlet UISegmentedControl *Segment; } //@property (nonatomic) IBOutlet UITextField *itemSearch; @property (weak, nonatomic) IBOutlet UITextField *minPrice; @property (weak, nonatomic) IBOutlet UITextField *maxPrice; @property (nonatomic, copy) NSNumber *chosenCategory; @property (weak, nonatomic) NSString *itemCondition; @property (weak, nonatomic) NSString *itemLocation; @property (weak, nonatomic) NSString *itemSearch; @end ``` CriteriaViewController.m: ``` #import "CriteriaViewController.h" @interface CriteriaViewController () @property (weak, nonatomic) IBOutlet UISegmentedControl *itemConditionSegment; @property (weak, nonatomic) IBOutlet UISegmentedControl *itemLocationSegment; @end @implementation CriteriaViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Condition UISegment UISegmentedControl *conditionSegmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"Only New", @"Any", nil]]; conditionSegmentedControl.frame = CGRectMake(87, 190, 157, 30); conditionSegmentedControl.selectedSegmentIndex = 0; conditionSegmentedControl.tintColor = [UIColor blackColor]; [conditionSegmentedControl addTarget:self action:@selector(ConditionSegmentControlAction:) forControlEvents: UIControlEventValueChanged]; [self.view addSubview:conditionSegmentedControl]; // Location UISegment UISegmentedControl *locationSegmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"Fast Shipping", @"Large Selection", nil]]; locationSegmentedControl.frame = CGRectMake(67, 275, 200, 30); locationSegmentedControl.selectedSegmentIndex = 0; locationSegmentedControl.tintColor = [UIColor blackColor]; [locationSegmentedControl addTarget:self action:@selector(LocationSegmentControlAction:) forControlEvents: UIControlEventValueChanged]; [self.view addSubview:locationSegmentedControl]; // Submit button UIButton *submitButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; // Create Round Rect Type button. submitButton.frame = CGRectMake(100, 100, 100, 100); // define position and width and height for the button. [submitButton setTitle:@"Submit" forState:UIControlStateNormal]; [submitButton addTarget:self action:@selector(submitButton:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:submitButton]; } - (void)ConditionSegmentControlAction:(UISegmentedControl *)segment { if(segment.selectedSegmentIndex == 0) { // set condition to new self.itemCondition = @"new"; } else if (segment.selectedSegmentIndex == 1) { // set condition to all self.itemCondition = @"all"; } } - (void)LocationSegmentControlAction:(UISegmentedControl *)segment { if(segment.selectedSegmentIndex == 0) { // set location to us self.itemLocation = @"US"; } else if (segment.selectedSegmentIndex == 1) { // set clocation to worldwide self.itemLocation = @"Worldwide"; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } //add all the info to users respective new category object - (IBAction)submitButton:(id)sender { if (self.minPrice.text.length > 0 && self.maxPrice.text.length > 0) { [PFCloud callFunctionInBackground:@"userCategorySave" withParameters:@{@"categoryId": self.chosenCategory, @"minPrice": self.minPrice, @"maxPrice": self.maxPrice, @"itemCondition": self.itemCondition, @"itemLocation": self.itemLocation } block:^(NSString *result, NSError *error) { if (!error) { NSLog(@"Criteria successfully saved."); [self performSegueWithIdentifier:@"SearchCategoryChooserToMatchCenterSegue" sender:self]; } }]; } } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { [PFCloud callFunctionInBackground:@"addToMatchCenter" withParameters:@{ // @"searchTerm": self.itemSearch, @"categoryId": self.chosenCategory, // @"minPrice": self.minPrice, // @"maxPrice": self.maxPrice, // @"itemCondition": self.itemCondition, // @"itemLocation": self.itemLocation, } block:^(NSString *result, NSError *error) { if (!error) { NSLog(@"'%@'", result); } }]; // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } @end ``` Cloud Code: ``` Parse.Cloud.define("userCategorySave", function(request, response) { var userCategory = Parse.Object.extend("userCategory"); var newUserCategory = new userCategory(); newUserCategory.set("categoryId", request.params.categoryId); newUserCategory.set("minPrice", request.params.minPrice); newUserCategory.set("maxPrice", request.params.maxPrice); newUserCategory.set("itemCondition", request.params.itemCondition); newUserCategory.set("itemLocation", request.params.itemLocation); newUserCategory.set("parent", Parse.User.current()); newUserCategory.save({ success: function (){ console.log ('userCategory successfully created!'); response.success('userCategory successfully created!'); }, error: function (){ console.log('error!!!'); response.error('Request failed'); } }); }); ``` I assume the issue is that the UITextFields are sending the numbers in a format my cloud code doesn't like. In addition to this error, I would like to set it so that only numbers are allowed when inputting a value in this field. How can I programmatically create these two fields in a way that will send the data in a format thats compatible with the cloud code, and that only allows numbers?

Original source

Related problems