我想检查用户是否有打开的购物篮,如果没有的话,将其发送到菜单,然后将其发送到我的打开购物篮视图,但是我遇到了错误。
所以我的问题是如何摆脱这个问题?我的逻辑对吗?

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

最佳答案

这个错误:

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

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

因此,请非常仔细地查看商家的定义。您是否在merchantId中正确掌握了fieldMappings的拼写?它是带有大写D的merchantID吗?

如果您确定商家确切具有一个名为merchantId的属性,那么下一个可能的事情是0x7fad19529490上的对象不是商家。

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

但是请使用错误中的地址。如果是商人,我希望它说出类似以下内容:
<Merchant: 0x7fad19529490>

或者,如果您重写了description,它将作为该输出。

关于ios - 如何调试“发送到实例的无法识别的选择器”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37928924/

10-12 14:38