我有两个UITextField
个框,一个用于minPrice,另一个用于maxPrice。当我尝试运行submitButton
IBAction
触发的函数时,使用这两个文本字段内容作为参数,它指出对象为空,并出现以下错误:
'*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]'
我似乎无法弄清楚为什么输入这些字段的文字没有正确保存。当我以编程方式初始化它时,我忘记了什么吗?
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 (nonatomic, copy) NSString *chosenCategoryName;
@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];
[self addMinTextField];
[self addMaxTextField];
// 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)addMinTextField{
// This allocates a label
UILabel *prefixLabel = [[UILabel alloc]initWithFrame:CGRectZero];
// This sets the font for the label
[prefixLabel setFont:[UIFont boldSystemFontOfSize:14]];
// This fits the frame to size of the text
[prefixLabel sizeToFit];
// This allocates the textfield and sets its frame
UITextField *minPrice = [[UITextField alloc] initWithFrame:
CGRectMake(70, 105, 75, 30)];
// This sets the border style of the text field
minPrice.borderStyle = UITextBorderStyleRoundedRect;
minPrice.contentVerticalAlignment =
UIControlContentVerticalAlignmentCenter;
[minPrice setFont:[UIFont boldSystemFontOfSize:12]];
//Placeholder text
minPrice.placeholder = @"150";
//Prefix label is set as left view and the text starts after that
minPrice.leftView = prefixLabel;
//It set when the left prefixLabel to be displayed
minPrice.leftViewMode = UITextFieldViewModeAlways;
// Adds the textField to the view.
[self.view addSubview:minPrice];
// sets the delegate to the current class
minPrice.delegate = self;
}
-(void)addMaxTextField{
// This allocates a label
UILabel *prefixLabel = [[UILabel alloc]initWithFrame:CGRectZero];
// This sets the font for the label
[prefixLabel setFont:[UIFont boldSystemFontOfSize:14]];
// This fits the frame to size of the text
[prefixLabel sizeToFit];
UITextField *maxPrice = [[UITextField alloc] initWithFrame:
CGRectMake(185, 105, 75, 30)];
//for max price
maxPrice.borderStyle = UITextBorderStyleRoundedRect;
maxPrice.contentVerticalAlignment =
UIControlContentVerticalAlignmentCenter;
[maxPrice setFont:[UIFont boldSystemFontOfSize:12]];
//Placeholder text is displayed when no text is typed
maxPrice.placeholder = @"300";
//Prefix label is set as left view and the text starts after that
maxPrice.leftView = prefixLabel;
//It set when the left prefixLabel to be displayed
maxPrice.leftViewMode = UITextFieldViewModeAlways;
// Adds the textField to the view.
[self.view addSubview:maxPrice];
// sets the delegate to the current class
maxPrice.delegate = self;
}
- (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.minPriceField.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,
@"categoryName": self.chosenCategoryName,
}
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
答案 0 :(得分:7)
您正在使用包含一个或多个NSDictionary
值的速记@{ key, value}
创建nil
。
作为开发阶段的预防技巧,我建议您使用以下方式检查所有value(s)
:
NSParameterAssert(self.itemSearch);
NSParameterAssert(self.chosenCategory);
// etc.
这将抛出一个断言,让你知道你的NSDictionary构造必然会失败。
现在有原因(在您的代码中)...... 如评论中所述,您使用局部变量在本地覆盖类成员的范围:
// This allocates the textfield and sets its frame
UITextField *minPrice = ...
考虑使用这种结构(如果没有,当然,使用IB创建UI对象,您似乎要这样做)
self.minPrice = ({
UITextField *minPrice = [[UITextField alloc] init...];
// more initialization of minPrice...
minPrice;
});
[self.view addSubview:self.minPrice];