NSPlaceholderDictionary:尝试从对象插入nil对象[1]

时间:2014-07-06 23:48:14

标签: ios objective-c uitextfield

我有两个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

1 个答案:

答案 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];