Цель-c noob здесь. Я испытываю ошибку EXC_BAD_ACCESS
в своих тестах и не могу понять, почему. Я написал класс Cart
для моего приложения, представляющего корзину пользователя. A Cart
может иметь несколько Order
s, хранящихся в массиве. Я пытаюсь реализовать соответствие KVO для массива Order
s с заданным кодом (извинения за длинный фрагмент кода, хочу убедиться, что все проблемы устранены). .h
файл:`EXC_BAD_ACCESS` в классе, реализующем KVO
#import "Model.h"
@class Item;
@class Organization;
@class Order;
@interface Cart : NSObject
@property (copy, readonly, nonatomic) NSArray *orders;
- (instancetype) init __attribute__((unavailable("init not available. Use `sharedCart`.")));
+ (instancetype)sharedCart;
- (void)setItem:(Item *)item withQuantity:(NSNumber *)quantity;
- (void)removeItem:(Item *)item;
- (NSNumber *)itemCount;
- (Order *)orderForSeller:(Organization *)seller;
@end
И .m
:
@interface Cart()
- (void)addOrder:(Order *)order;
- (void)removeOrder:(Order *)order;
@property (copy, readwrite, nonatomic) NSArray *orders;
@end
NSString * const ordersKey = @"orders";
@implementation Cart
{
NSMutableArray *_orders;
}
@synthesize orders = _orders;
+ (instancetype)sharedCart {
static dispatch_once_t onceToken;
static Cart *cart;
dispatch_once(&onceToken, ^{
cart = [[Cart alloc] initPrivate];
});
return cart;
}
- (void)insertObject:(Order *)order inOrdersAtIndex:(NSUInteger)index {
[_orders insertObject:order atIndex:index];
}
- (void)removeObjectFromOrdersAtIndex:(NSUInteger)index {
[_orders removeObjectAtIndex:index];
}
- (void)setOrders:(NSArray *)array {
if (array != _orders) {
_orders = [array mutableCopy];
}
}
- (instancetype)initPrivate {
self = [super init];
if (self) {
self = [super init];
_orders = [[NSMutableArray alloc] init];
}
return self;
}
+ (instancetype)object {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Can not create new Cart instance. Used [Cart sharedCart]" userInfo:nil];
}
-(Order *)orderForSeller:(Organization *)seller {
for (Order *order in self.orders) {
if ([order.seller is:seller]) {
return order;
}
}
return nil;
}
- (void)setItem:(Item *)item withQuantity:(NSNumber *)quantity {
Order *order = [self orderForSeller:item.seller];
if (!order) {
order = [Order object];
order.seller = item.seller;
order.user = [User currentUser];
[self addOrder:order];
}
[order setItem:item withQuantity:quantity];
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
// If an order is ever empty, remove it from cart.
if ([object isKindOfClass:[Order class]] && [keyPath isEqualToString:@"orderItems"]) {
Order *order = (Order *)object;
if ([[order itemCount] integerValue] == 0) {
[self removeOrder:order];
}
}
// When orders are saved, remove them from cart.
if ([object isKindOfClass:[Order class]] && [keyPath isEqualToString:@"isNew"]) {
Order *order = (Order *)object;
BOOL orderHasBeenPlaced = ![order isNew];
if (orderHasBeenPlaced) {
[self removeOrder:order];
}
}
}
- (void)addOrder:(Order *)order {
[order addObserver:self forKeyPath:@"orderItems" options:NSKeyValueObservingOptionNew context:nil];
[order addObserver:self forKeyPath:@"isNew" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
[self insertObject:order inOrdersAtIndex:[_orders count]];
}
-(void)removeOrder:(Order *)order {
[order removeObserver:self forKeyPath:@"orderItems"];
[order removeObserver:self forKeyPath:@"isNew"];
NSUInteger index = [_orders indexOfObject:order];
[self removeObjectFromOrdersAtIndex:index];
}
-(void)removeItem:(Item *)item {
Order *order = [self orderForSeller:item.seller];
if (order) {
[order removeItem:item];
}
}
-(NSNumber *)itemCount {
return [self.orders valueForKeyPath:@"@sum.itemCount"];
}
- (void)dealloc {
for (Order *order in self.orders) {
[order removeObserver:self forKeyPath:@"isNew"];
[order removeObserver:self forKeyPath:@"orderItems"];
}
}
@end
метод addOrder:
продюсирует EXC_BAD_ACCESS
исключение на этой линии:
[self insertObject:order inOrdersAtIndex:[_orders count]];
Debugging, то _orders
массив является действительным NSMutableArray
, Кто-нибудь знает, что происходит? Очень признателен.
`
Запустите свой код с помощью диагностического знака NSZombieEnable, который поможет вам найти причину такого плохого доступа. https: // StackOverflow.com/questions/5386160/how-to-enable-nszombie-in-xcode –