ios NSPlaceholderDictionary:尝试从对象中插入 nil 对象 [1]
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24601377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NSPlaceholderDictionary: attempt to insert nil object from objects[1]
提问by Ghobs
I have two UITextField
boxes, one for minPrice, and one for maxPrice. When I attempt to run the function triggered by the submitButton
IBAction
, using those two textfield contents as parameters, it states that the objects are empty with the following error:
我有两个UITextField
盒子,一个用于 minPrice,一个用于 maxPrice。当我尝试运行由 触发的函数时submitButton
IBAction
,使用这两个文本字段内容作为参数,它指出对象为空,并出现以下错误:
'*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]'
'*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]'
I can't seem to figure out why the text that is input into these fields isn't saved properly. Am I forgetting something when I programmatically initialize them?
我似乎无法弄清楚为什么输入到这些字段中的文本没有正确保存。当我以编程方式初始化它们时,我是否忘记了什么?
CriteriaViewController.h:
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:
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
回答by SwiftArchitect
You are creating a NSDictionary
using the shorthand @{ key, value}
with one or more nil
value.
您正在NSDictionary
使用@{ key, value}
具有一个或多个nil
值的速记创建一个。
As a preventive technique at the development stage, may I suggest checking all your value(s)
using:
作为开发阶段的预防技术,我建议您检查所有value(s)
使用情况:
NSParameterAssert(self.itemSearch);
NSParameterAssert(self.chosenCategory);
// etc.
This will throw an assert and let you know that your NSDictionary construction is bound to fail.
这将抛出一个断言,并让您知道您的 NSDictionary 构造肯定会失败。
Now for causes (in your code)...As stated in the comments, you are locally overriding the scope of your class members with local variables:
现在对于原因(在您的代码中)......如评论中所述,您正在使用局部变量在本地覆盖类成员的范围:
// This allocates the textfield and sets its frame
UITextField *minPrice = ...
Consider using this construction (if not, of course, creating the UI objects with IB, which you appear to do)
考虑使用这种构造(如果没有,当然,使用 IB 创建 UI 对象,您似乎这样做)
self.minPrice = ({
UITextField *minPrice = [[UITextField alloc] init...];
// more initialization of minPrice...
minPrice;
});
[self.view addSubview:self.minPrice];