【问题标题】:'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[3]''NSInvalidArgumentException',原因:'*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]:尝试从对象 [3] 中插入 nil 对象'
【发布时间】:2014-07-16 20:35:38
【问题描述】:

我的故事板中有两个UITextFields,用于接收用户输入的数字,即 minPrice 和 maxPrice。当我在模拟器中单击提交时,应用程序崩溃并收到以下错误:

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

云代码:

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');
        }

      });
});

我认为问题在于 UITextFields 以我的云代码不喜欢的格式发送数字。除了这个错误,我想设置它,以便在该字段中输入值时只允许数字。

如何以与云代码兼容且仅允许数字的格式发送数据的方式以编程方式创建这两个字段?

【问题讨论】:

  • 而不是假设问题是什么,而是发布大量代码并期望人们看到它。如果您学会了如何使用 Xcode 进行交互式调试,那么您将能够找到导致问题的确切代码行,然后无需再假设问题可能是什么。
  • 我很抱歉,你是对的。我在哪里可以学习调试此类错误?
  • 基本调试与最初的错误类型无关。 XCode 能够单步执行、进入一行代码。只需使用该能力找出问题所在。您不断地在 SO 上发布一个又一个问题,您显然甚至没有尝试找出问题所在的哪里。一旦你找出 where 那么 why 通常是显而易见的,尤其是结合 reading 错误消息时。
  • PlaceholderDictionary 是一个文字字典,在通过文字语法 @{} 创建字典的地方会发生崩溃,显然其中一个值是 nil。为所有 Objective-C 异常添加断点并查看它崩溃的位置。
  • 很多 cmets 建议你学习 iOS 调试,没有一个指向 a tutorial - 这个看起来不错,但我希望花时间评论的更多有帮助的人会提出更好的建议。在这种情况下,您最好打开exception breakpoint

标签: ios objective-c uitextfield


【解决方案1】:

你的一个属性——看起来像itemCondition——显然是零。这可能是因为您的属性很弱,因此变量在您有机会查看它之前就被清空了,或者可能是因为您选择的段不是您正在测试的值之一,因此变量从未设置。我不明白为什么这些字符串属性很弱,我强烈怀疑它们不应该如此。

【讨论】:

  • 很好找到。用self.itemCondition = @"all"; 分配一个弱引用变量将永远不会起作用。所有内存将在该方法范围结束时释放。如果他将其分配为对另一个变量的弱引用,那么有机会,但不是本地分配的内存。
  • 好吧,我真的只是在详细说明错误消息。它说 objects[3] 在submitButton: 方法的字典构造函数中为零,所以我只是在该方法中搜索@{ 并调出第四项。老实说,我无法理解为什么指向常量字符串的变量会因为它们是不朽的而被清空(这就是我提供替代理论的原因),但是错误消息强烈表明它是 nil ,而弱属性真的没有多大意义。
【解决方案2】:

如果是关于 NSDictionary...

NSDictionary *dic = @{@"id":ID,
                      @"condition":condition,
                      @"pageNo":[NSNumber numberWithInt:pageNo],
                      @"pageSize":[NSNumber numberWithInt:pageSize]};

这不好。如果任何对象为 nil,那么它就会有问题。


NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:
                         ID,@"id",
                         condition,@"condition",
                         [NSNumber numberWithInt:pageNo],@"pageNo",
                         [NSNumber numberWithInt:pageSize],@"pageSize",
                         nil];

这是对的。

【讨论】:

  • 使用这种方法,我能够调试并弄清楚究竟什么值是 nil
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 2017-12-16
  • 1970-01-01
  • 2020-11-08
  • 2012-08-09
  • 2016-05-23
相关资源
最近更新 更多