如何调试“无法识别的选择器发送到实例”

时间:2016-06-20 17:58:30

标签: ios objective-c

我想检查用户是否有一个开放的篮子,如果是这样,如果没有将它们发送到菜单然后发送发送到我的开放篮子视图但我收到错误。 所以我的问题是如何摆脱这个问题?我的逻辑是对的吗?

  'NSInvalidArgumentException', reason: '-[Merchant merchantId]: unrecognized selector sent to instance 0x7fad19529490'.

我在菜单视图中按下按钮addToOrderButtonTapped时使用此方法检查开放式篮子

    [[OrderManager sharedManager]getBasketsForMerchant:merchant success:^(NSArray *baskets) {
        for (Basket *basket in baskets){
            if ([basket.status isEqualToString:kBasketStatusOpen]) {
                [self.openBaskets addObject:basket];
            }
        }if (self.openBaskets.count > 0){
            self.openBaskets = self.openBaskets;
            dispatch_async(dispatch_get_main_queue(), ^{
                [self performSegueWithIdentifier:kSegueMenu sender:self];
            });
        }
        else {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self performSegueWithIdentifier:KSegueOpenBasket sender:self];
            });
        }
    } failure:^(NSError *error, NSHTTPURLResponse *response) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSString *localizedString = NSLocalizedString(@"Order.ErrorLoadingOpenOrders", "Get error message");
            [self showMessage:localizedString withTitle:MessageTypeError];
            [MBProgressHUD hideAllHUDsForView:self.view animated:YES];
        });
    }];

菜单视图

 //
 //  MenuItemViewController.m
 //  BaseApp
 //

  #import "MenuItemViewController.h"
  #import "RoundedButton.h"
  #import "MenuOptionCell.h"
  #import "MenuItem.h"
  #import "MenuOptionButton.h"
  #import "MenuChoice.h"
  #import "OrderManager.h"
  #import "TypeOfChoiceCell.h"
  #import "MenuOption.h"
  #import "OrderPricingTableViewCell.h"
  #import "RKManagedObjectStore.h"
  #import "NSManagedObjectContext+RKAdditions.h"
  #import "MerchantManager.h"
  #import "Merchant.h"
  #import "OrdersViewController.h"
  #import "MenuItem.h"
  #import "MenuViewController.h"
  #import "OrderConfirmationViewController.h"
  #import "OrderManager.h"
  #import "APIClient.h"
  #import "MenuManager.h"
  #import "DiscoverViewController.h"
  #import "DiscoverCollectionViewCell.h"
  #import "MerchantManager.h"
  #import "MenuViewController.h"
  #import "MenuManager.h"
  #import "MerchantDetailsViewController.h"
  #import "OpenOrdersViewController.h"

   typedef NS_ENUM(NSUInteger, MenuOptionsSection) {
MenuOptionsSectionRequired = 0,
MenuOptionsSectionOptional = 1
 };
 static NSString *const OpenBasketsSegue = @"OpenBaskets";
 static NSString *const kSegueMenu = @"ShowMenu";
 static NSString *const KSegueOpenBasket = @"OpenBaskets";
 @interface MenuItemViewController () <UITableViewDelegate,   UITableViewDataSource>

  @property (nonatomic, weak) IBOutlet UILabel *menuItemName;
  @property (nonatomic, weak) IBOutlet UILabel *quantityLabel;
  @property (nonatomic, weak) IBOutlet UILabel *menuItemPrice;
  @property (nonatomic, weak) IBOutlet UILabel *subTotalLabel;
  @property (nonatomic, weak) IBOutlet UITextView *menuItemDescription;
  @property (nonatomic, weak) IBOutlet RoundedButton *addToOrderButton;
  @property (nonatomic, weak) IBOutlet UITableView *tableView;
  @property (nonatomic, weak) IBOutlet UIView *cartView;
  @property (nonatomic, weak) IBOutlet UIButton *subtractButton;
  @property (nonatomic) NSDecimalNumber *temporarySubtotal;
  @property (nonatomic, strong) NSMutableArray<MenuOption *>  *requiredChoices;
  @property (nonatomic, strong) NSMutableArray<MenuOption *> *optionalChoices;
  @property (nonatomic, strong) NSMutableArray<NSMutableArray *>  *optionChoicesSection;
  @property (nonatomic, strong) NSMutableArray<NSDictionary *> *options;
  @property (nonatomic, strong) NSMutableArray <Basket *>*openBaskets;
  @property (nonatomic) BOOL launchViewFirstTime;

   @end

   @implementation MenuItemViewController


   #pragma - Lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"Menu Item";
self.menuItemName.text = self.menuCategory.selectedBasketLine.menuItem.name;
self.menuItemPrice.text = [NSString stringWithFormat:@"%@", [Basket  formattedCurrencyStringForAmount:self.menuCategory.selectedBasketLine.menuItem.price]];
self.quantityLabel.text = self.menuCategory.selectedBasketLine.quantity.stringValue;
self.temporarySubtotal = [self calculateTemporarySubtotal:[OrderManager sharedManager].currentBasket.subtotal menuItemPrice:self.menuCategory.selectedBasketLine.menuItem.price];
[self setSubtotalText:self.temporarySubtotal];
self.menuItemDescription.text = self.menuCategory.selectedBasketLine.menuItem.menuItemDescription;
self.subtractButton.alpha = 0.65;
self.requiredChoices = [[NSMutableArray alloc] init];
self.optionalChoices = [[NSMutableArray alloc] init];
self.optionChoicesSection = [[NSMutableArray alloc] init];
self.options = [[NSMutableArray alloc] init];
[self initializeChoiceArrays];
self.tableView.delegate = self;
self.tableView.dataSource = self;
     }

   - (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.launchViewFirstTime = YES;
if (self.optionChoicesSection.count > 0) {
    [self.tableView reloadData];
      } else {
    self.tableView.hidden = YES;
      }
      }

    - (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.launchViewFirstTime = NO;
     }

    - (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
for (MenuOption *menuOption in self.requiredChoices) {
    [menuOption resetNumberOfChoicesSelected];
      }
for (MenuOption *menuOption in self.optionalChoices) {
    [menuOption resetNumberOfChoicesSelected];
      }
self.menuCategory = nil;
     }

    - (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self.menuItemDescription setContentOffset:CGPointZero animated:YES];
     }


   #pragma - IBActions
   - (IBAction)addButtonTapped:(id)sender {
NSInteger count = self.quantityLabel.text.integerValue;
count++;
if (count > 1) {
    self.subtractButton.alpha = 1;
}
NSDecimalNumber *newSubTotal = [self.temporarySubtotal decimalNumberByAdding:self.menuCategory.selectedBasketLine.menuItem.price];
[self modifyCurrentBasketSubtotal:newSubTotal quantity:count];
     }

   - (IBAction)subtractButtonTapped:(id)sender {
NSInteger count = self.quantityLabel.text.integerValue;
if (count > 1) {
    count--;
    NSDecimalNumber *newSubTotal = [self.temporarySubtotal decimalNumberBySubtracting:self.menuCategory.selectedBasketLine.menuItem.price];
    [self modifyCurrentBasketSubtotal:newSubTotal quantity:count];
    if (count == 1) {
        self.subtractButton.alpha = 0.65;
    }
    }
    }

   - (IBAction)addToOrderButtonTapped:(id)sender {
MenuOption *menuOption;
Merchant *merchant  = [[Merchant alloc]init];
// First check if there are any missing required options that have to be selected
if ((menuOption = [self checkMissingRequiredOptionsHaveBeenSelected])) {
    NSString *localizedString = NSLocalizedString(@"AddMenuItem.RequiredChoicesNotSelected", @"Get string for error");
    NSString *formattedString = [NSString stringWithFormat:localizedString, menuOption.name];
    [self showMessage:formattedString withTitle:MessageTypeError];
    return;
}
// Now check if the minimum and maximum choice seletion have been met for the menu options
if ((menuOption = [self validateMinMaxForMenuOptionsHaveBeenMet])) {
    NSString *localizedString = NSLocalizedString(@"AddMenuItem.MinMaxNotFulfilled", @"Get string for error");
    NSString *formattedString = [NSString stringWithFormat:localizedString, menuOption.name];
    [self showMessage:formattedString withTitle:MessageTypeError];
    return;
    }
// Add the menu item to the basket
     if (self.menuItemAddedBlock) {
    self.menuItemAddedBlock(self, self.menuCategory);
   // [self dismissViewControllerAnimated:YES completion:nil];

     //checking for open basket here 
    [[OrderManager sharedManager]getBasketsForMerchant:merchant success:^(NSArray *baskets) {
        for (Basket *basket in baskets){
            if ([basket.status isEqualToString:kBasketStatusOpen]) {
                [self.openBaskets addObject:basket];
            }
        }if (self.openBaskets.count > 0){
            self.openBaskets = self.openBaskets;
            dispatch_async(dispatch_get_main_queue(), ^{
                [self performSegueWithIdentifier:kSegueMenu sender:self];
            });
        }
        else {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self performSegueWithIdentifier:KSegueOpenBasket sender:self];
            });
        }
    } failure:^(NSError *error, NSHTTPURLResponse *response) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSString *localizedString = NSLocalizedString(@"Order.ErrorLoadingOpenOrders", "Get error message");
            [self showMessage:localizedString withTitle:MessageTypeError];
            [MBProgressHUD hideAllHUDsForView:self.view animated:YES];
        });
    }];


     }
     }

   - (IBAction)cancelButtonTapped:(UIBarButtonItem *)sender {
[self dismissViewControllerAnimated:YES completion:nil];
     }


      #pragma - UITableViewDelegate, UITableViewDataSource
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.optionChoicesSection.count;
     }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.optionChoicesSection[section].count;
     }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MenuOptionCell *cell = (MenuOptionCell *)[tableView dequeueReusableCellWithIdentifier:[MenuOptionCell reuseIdentifier]];
cell.menuOption = self.optionChoicesSection[indexPath.section][indexPath.row];
cell.menuOptionCellButtonPressedBlock = ^(MenuOptionButton *button, MenuOption *option, MenuChoice *choice) {
    [self adjustSelectedOptions:option choice:choice indexPath:indexPath];
};
cell.menuOptionCellDefaultOptionDetectedBlock = ^(MenuOptionButton *button, MenuOption *option, MenuChoice *choice) {
    [self adjustSelectedOptions:option choice:choice indexPath:indexPath];
     };
cell.menuOptionCellDeselectedBlock = ^(MenuOptionButton *button, MenuOption *option, MenuChoice *choice) {
    [self adjustSelectedOptions:option choice:choice indexPath:indexPath];
      };
[cell configureCell:self.launchViewFirstTime];
return cell;
     }

     - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
TypeOfChoiceCell *cell = (TypeOfChoiceCell *)[tableView dequeueReusableCellWithIdentifier:[TypeOfChoiceCell reuseIdentifier]];
switch ((MenuOptionsSection)section) {
    case MenuOptionsSectionRequired:
        if (self.requiredChoices.count > 0) {
            cell.title =  NSLocalizedString(@"AddMenuItem.RequiredChoiceText", @"Get string for title");
            return cell;
        } else if (self.optionalChoices.count > 0) {
            cell.title =  NSLocalizedString(@"AddMenuItem.OptionalChoiceText", @"get string for title");
            return cell;
        }
    case MenuOptionsSectionOptional:
        if (self.optionalChoices.count > 0) {
            cell.title =   NSLocalizedString(@"AddMenuItem.OptionalChoiceText", @"Get string for title");
            return cell;
        }
        }
return nil;
        }

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
MenuOption *option = self.optionChoicesSection[indexPath.section][indexPath.row];
return [MenuOptionCell heightForMenuOption:option];
      }

    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return [TypeOfChoiceCell height];
       }

    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0.01f;
        }


       #pragma - Helpers
    - (void)setSubtotalText:(NSDecimalNumber *)subtotal {
if (!subtotal) {
    self.subTotalLabel.text = NSLocalizedString(@"AddMenuItem.SubtotalDefault", @"Get string for subtotal");
} else {
    NSString *localizedString = NSLocalizedString(@"AddMenuItem.SubtotalFormatted", @"Get string for subtotal");
    self.subTotalLabel.text = [NSString stringWithFormat:localizedString, [Basket formattedCurrencyStringForAmount:subtotal]];
      }
      }

    - (void)modifyCurrentBasketSubtotal:(NSDecimalNumber *)subtotal quantity:(NSInteger)quantity {
self.menuCategory.selectedBasketLine.quantity = [NSNumber numberWithInteger:quantity];
self.menuCategory.selectedBasketLine.subtotal = subtotal;
self.temporarySubtotal = subtotal;
[self setSubtotalText:subtotal];
self.quantityLabel.text = self.menuCategory.selectedBasketLine.quantity.stringValue;
     }

    - (NSDecimalNumber *)calculateTemporarySubtotal:(NSDecimalNumber *)orderManagerSubTotal menuItemPrice:(NSDecimalNumber *)menuItemPrice {
if (orderManagerSubTotal == 0) {
    return menuItemPrice;
} else {
    return [orderManagerSubTotal decimalNumberByAdding:menuItemPrice];
      }
     }

     - (MenuOption *)checkMissingRequiredOptionsHaveBeenSelected {
for (MenuOption *menuOption in self.requiredChoices) {
    if (!menuOption.selected) {
        return menuOption;
    }
     }
return nil;
     }

    - (MenuOption *)validateMinMaxForMenuOptionsHaveBeenMet {
for (MenuOption *menuOption in self.requiredChoices) {
    if ([menuOption validateIndividualMinMaxForMenuOption]) {
        return menuOption;
    }
}
for (MenuOption *menuOption in self.optionalChoices) {
    if (menuOption.selected) {
        if ([menuOption validateIndividualMinMaxForMenuOption]) {
            return menuOption;
        }
        }
        }
     return nil;
         }

    - (void)initializeChoiceArrays {
NSArray<MenuOption *> *menuOptions = [self.menuCategory.selectedBasketLine.menuItem.menuOptions allObjects];
for (MenuOption *menuOption in menuOptions) {
    if (menuOption.minimumChoices == nil) {
        menuOption.minimumChoices = [NSNumber numberWithInt:0];
    }
    if (menuOption.maximumChoices == nil) {
        menuOption.maximumChoices = [NSNumber numberWithInt:0];
    }
    // For now make an optional choice required if minimumChoices > 0
    if (menuOption.isRequired || [menuOption.minimumChoices intValue] > 0) {
        menuOption.isRequired = YES;
        [self.requiredChoices addObject:menuOption];
     } else {
        [self.optionalChoices addObject:menuOption];
     }
     }
if (self.requiredChoices.count > 0) {
    [self.optionChoicesSection addObject:self.requiredChoices];
    }
 if (self.optionalChoices.count > 0) {
    [self.optionChoicesSection addObject:self.optionalChoices];
    }
    }

    - (void)adjustSelectedOptions:(MenuOption *)option choice:(MenuChoice *)choice indexPath:(NSIndexPath *)indexPath {
self.menuCategory.selectedBasketLine.subtotal = self.menuCategory.selectedBasketLine.menuItem.price;
if (option.selected && option.menuChoices.count == 0) {
    [self.options addObject:@{kOption: option.menuOptionId ?: @"", kChoice: @""}];
    if (option.price) {
        self.temporarySubtotal = [self.temporarySubtotal decimalNumberByAdding:option.price];
    }
    if (option.isRequired) {
        self.requiredChoices[indexPath.row].selected = option.selected;
        self.requiredChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
    } else {
        self.optionalChoices[indexPath.row].selected = option.selected;
        self.optionalChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
    }
    } else {
    if (option.menuChoices.count == 0) {
        [self.options removeObject:@{kOption: option.menuOptionId ?: @"", kChoice: @""}];
        if (option.price) {
            self.temporarySubtotal = [self.temporarySubtotal decimalNumberBySubtracting:option.price];
        }
        if (option.isRequired) {
            self.requiredChoices[indexPath.row].selected = option.selected;
            self.requiredChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
        } else {
            self.optionalChoices[indexPath.row].selected = option.selected;
            self.optionalChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
        }
        }
        }
if (choice.selected && option.menuChoices.count > 0) {
    [self.options addObject:@{kOption: choice.menuOption.menuOptionId ?: @"", kChoice: choice.menuChoiceId ?: @""}];
    if (choice.price) {
        self.temporarySubtotal = [self.temporarySubtotal decimalNumberByAdding:choice.price];
     }
    if (option.isRequired) {
        self.requiredChoices[indexPath.row].selected = choice.selected;
        self.requiredChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
    } else {
        self.optionalChoices[indexPath.row].selected = choice.selected;
        self.optionalChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
       }
    } else {
    if (option.menuChoices.count > 0) {
        [self.options removeObject:@{kOption: choice.menuOption.menuOptionId ?: @"", kChoice: choice.menuChoiceId ?: @""}];
        if (choice.price) {
            self.temporarySubtotal = [self.temporarySubtotal decimalNumberBySubtracting:choice.price];
        }
        if (option.isRequired) {
            if ([option.numberOfChoicesSelected intValue] == 0) {
               self.requiredChoices[indexPath.row].selected = option.selected;
            } else {
                self.requiredChoices[indexPath.row].selected = !choice.selected;
            }
            self.requiredChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
        } else {
            self.optionalChoices[indexPath.row].selected = choice.selected;
            self.optionalChoices[indexPath.row].numberOfChoicesSelected = option.numberOfChoicesSelected;
        }
     }
    }
   [self setSubtotalText:self.temporarySubtotal];
self.menuCategory.selectedBasketLine.attributes = self.options;
    }

     @end

这是给我错误的代码行

 + (void)getBasketsForMerchant:(Merchant *)merchant success:(void (^)(NSArray *basket))success failure:(void (^)(NSError *, NSHTTPURLResponse *))failure {
NSMutableDictionary* params = @{@"expand": @"merchant"}.mutableCopy;
if (merchant) {
   params[@"merchant"] = merchant.merchantId;
}
[[RKObjectManager sharedManager] getObjectsAtPath:kOrdersEndpoint parameters:params success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult){
    NSArray* items = mappingResult.array;
    if (success) {
    success(items);
    }
 } failure:^(RKObjectRequestOperation *operation, NSError *error) {
   if (failure) {
      failure(error, operation.HTTPRequestOperation.response);
   } else {
        _defaultFailureBlock(operation, error);
   }
 }];
 }

1 个答案:

答案 0 :(得分:3)

此错误:

'NSInvalidArgumentException', reason: '-[Merchant merchantId]: unrecognized selector sent to instance 0x7fad19529490'.

表示您在位置0x7fad19529490处有一个对象,并且您尝试在其上调用“merchantId”。该对象不响应merchantId

所以,仔细看看Merchant的定义。您是否在merchantId中获得了fieldMappings的拼写?是merchantID是否有大写D?

如果您确定商家确实拥有名为merchantId的商家,则下一个可能是0x7fad19529490处的商品不是商家。

最简单的方法是在断点导航器的底部添加一个异常断点(使用+)。发生此异常时,从错误中获取指针地址(每次可能不同)并查看调试器中的内容。为此,请在(lldb)提示符下键入:

 po (NSObject*)(0x7fad19529490)

但使用错误中的地址。如果它是商家,我希望它能说:

<Merchant: 0x7fad19529490>

或者,如果您已覆盖description,则它将是该输出。