MVC 패턴을 따르려고 할 때 키 - 값 옵저버를 구현하는 데 문제가 있습니다. 컨트롤러 클래스, 모델 클래스 및 뷰 클래스가 있습니다. 내 모델을 컨트롤러 클래스에서 업데이트하고 NSMutableArray가 addObject와 같은 모델에서 변경된 후 자동으로 다시 그려지는 것을 모니터하기 위해 뷰 클래스에 키 값 옵저버를 넣고 싶습니다. (이 중요한 경우 스프라이트 키트를 사용하여)키 - 값 구현 처음 시도 할 때 약간의 오류가 발생합니다.
내 장면에서 : 지금까지 How to add observer on NSMutableArray?
코드 : 나는 나를 인도하는이 스레드에 대한 답변을 사용했다. 문자의 설정은 Ctrl 클래스에서 수행됩니다. 이것은 테스트하는 것입니다.
BarCtrl *barCtrl = [[BarCtrl alloc] init];
BarModel *barModel = [[BarModel alloc] init];
BarView *barView = [[BarView alloc] init];
barCtrl.barModel = barModel;
barCtrl.barView = barView;
barView.barModel = barModel;
ScrabbleDeck *sd = [[ScrabbleDeck alloc] init];
if([barModel addLetter:[sd getLetter] onSide:BarModelSideRight])
NSLog(@"Added letter");
BarModel.h
#import <Foundation/Foundation.h>
#import "Letter.h"
typedef NS_ENUM(int, BarModelSide) {
BarModelSideLeft,
BarModelSideRight
};
@interface BarModel : NSObject
@property (nonatomic, strong) NSMutableArray *addedLetters;
- (instancetype)init;
- (BOOL) addLetter: (Letter*) letter onSide: (BarModelSide) side;
@end
BarModel.m
#import "BarModel.h"
@interface BarModel()
@property (nonatomic) int capacity;
@end
@implementation BarModel
- (instancetype)init
{
self = [super init];
if (self) {
self.capacity = letterCapacity;
_addedLetters = [[NSMutableArray alloc] init];
}
return self;
}
// We'll use automatic notifications for this example
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
{
if ([key isEqualToString:@"arrayLetter"]) {
return YES;
}
return [super automaticallyNotifiesObserversForKey:key];
}
- (BOOL) addLetter: (Letter*) letter onSide: (BarModelSide) side{
if([_addedLetters count] > _capacity){
return FALSE;
}
switch (side) {
case BarModelSideLeft:
[_addedLetters insertObject:letter atIndex:0];
return TRUE;
break;
case BarModelSideRight:
[_addedLetters addObject:letter];
return TRUE;
break;
default:
return FALSE;
break;
}
}
// These methods enable KVC compliance
- (void)insertObject:(id)object inDataAtIndex:(NSUInteger)index
{
self.addedLetters[index] = object;
}
- (void)removeObjectFromDataAtIndex:(NSUInteger)index
{
[self.addedLetters removeObjectAtIndex:index];
}
- (id)objectInDataAtIndex:(NSUInteger)index
{
return self.addedLetters[index];
}
- (NSArray *)dataAtIndexes:(NSIndexSet *)indexes
{
return [self.addedLetters objectsAtIndexes:indexes];
}
- (NSUInteger)countOfData
{
return [self.addedLetters count];
}
@end
BarView.h
#import <SpriteKit/SpriteKit.h>
#import "BarModel.h"
@interface BarView : SKSpriteNode
@property (nonatomic, strong) BarModel *barModel;
@end
BarView.m
01 나는 RU이 나는이 "오류"를 얻을 때 23,168,464,437,673,181,239,093,210는 :
2014-08-31 00:23:02.828 Testing[329:60b] Added letter
2014-08-31 00:23:02.830 Testing[329:60b] An instance 0x17803d340 of class BarModel was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0x17804eb50> (
<NSKeyValueObservance 0x1780cf180: Observer: 0x178111670, Key path: arrayLetter, Options: <New: YES, Old: YES, Prior: NO> Context: 0x100101428, Property: 0x17804eb80>
나는 오류의 지시 사항을 따르려고 노력하지만 브레이크 포인트를 설정 위치를 찾을 수 없습니다. 이 문제를 해결하는 데 도움주세요!
Tom, 두 곳에서 제거를 수행하면 두 번 제거 될 수 있으며 예외가 발생합니다. 접근 자 내부에서 KVO 관찰을하는 이유 중 하나가 어렵습니다. – quellish
@quellish, 틀렸어. 세터에서의 제거는 대체되는 참조 용입니다. '-dealloc'에서의 제거는 해제시 현재의 참조를위한 것입니다. –