2016-06-20 3 views
1

Я хочу проверить, есть ли у пользователя открытая корзина, если они отправляют их в меню, если нет, тогда отправьте их в открытую корзину, но я получаю сообщение об ошибке. Итак, мой вопрос: как избавиться от этой проблемы? и моя логика права?Как отлаживать «непризнанный селектор, отправленный в экземпляр»

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

им, используя этот метод, чтобы проверить открытые корзины, когда кнопка addToOrderButtonTapped прессовой в menuview

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

menuview

// 
// 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); 
    } 
}]; 
} 
+2

В вашем вопросе слишком много кода, вы должны только вставить соответствующую часть ... – AnthoPak

+1

okay thanks i m собирается отредактировать его –

+0

Получается ли ошибка, вызванная тем, что строка выделяется в отладчике XCode? Было бы полезно узнать, какая строка запускает его с тех пор, как @AnthoninC. упоминает, что для нас существует большой объем кода. Если нет выделенной строки, попробуйте добавить точку останова на все исключения ala этот метод: [link] (http://stackoverflow.com/a/29486686/4191758) –

ответ

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, это будет выход из этого.

+1

Если объект не был «купечеством», тогда причина исключения указала бы какой бы класс был на самом деле, а не «торговец» – dan

+0

. Хорошо, я пытаюсь его, но да, его продавец. –

+0

так я только что получил это (lldb) ро 0x7fd3c50b1500 <Торговец: 0x7fd3c50b1500> (объект: ; идентификатор: (нуль); данные: ) <Торговец: 0x7fd3c50b1500> (объект: ; идентификатор: (нуль) , данные: ) –

Смежные вопросы