addObserver:forKeyPath вызывает сбой приложения, KVO, цель c
Я делаю эффект параллакса, используя категорию, выполняя:
add and UIView into the uitableView (via category
add addObserver:forKeyPath so that whenever tableview is moving, i will reframe the view above
Подробности ниже UIScrollView + Parallax.h
#import <UIKit/UIKit.h>
@class ParallaxView;
@interface UIScrollView (Parallax)
@property (strong, nonatomic) ParallaxView *parallaxView;
- (void) addParallaxViewWith:(UIView*)parallaxView;
- (void) removeKVO;
@end
@interface ParallaxView : UIView
@end
UIScrollView + Parallax.m
static char parallaxKey;
@implementation UIScrollView (Parallax)
@dynamic parallaxView;
#pragma mark - Add parallax view to scrollView
- (void) addParallaxViewWith:(ParallaxView*)pView {
if ( !self.parallaxView) {
[self addSubview:pView];
[self setParallaxView:pView];
}
}
#pragma mark - Set parallaxView + register parallaxView as an observer
- (void) setParallaxView:(ParallaxView *)parallaxView {
objc_setAssociatedObject(self, ¶llaxKey, parallaxView, OBJC_ASSOCIATION_ASSIGN);
/* THESE LINE ARE CRASHING THE APP */
// [self addObserver:self.parallaxView
// forKeyPath:@"contentOffset"
// options:NSKeyValueObservingOptionNew
// context:nil];
}
#pragma mark - Get parallaxView
- (ParallaxView*) parallaxView {
return (objc_getAssociatedObject(self, ¶llaxKey));
}
#pragma mark - Remove
- (void)removeKVO {
[self removeObserver:self.parallaxView forKeyPath:@"contentOffset"];
}
@end
@implementation ParallaxView
-(id)init
{
//load xib from main bundle and assign it to self
self = [[[NSBundle mainBundle]loadNibNamed:@"Parallex"
owner:self
options:nil] objectAtIndex:0];
return self;
}
-(id)initWithFrame:(CGRect)frame
{
self = [self init];
[self setFrame:frame];
return self;
}
................
@end
И я добавляю параллакс к таблице, делая
ParallaxView *pView = [[ParallaxView alloc]initWithFrame:CGRectMake(0, 0, 320, 160)];
[self.tableView addParallaxViewWith:pView];
Тем не мение, [self addObserver:forKeyPath:options:context:nil]
продолжает сбивать приложение безо всяких подсказок. Если я прокомментирую эту строку, и приложение не падает, но эффект параллекса не работает.
Любые идеи по этой проблематике. Пожалуйста помоги. Спасибо
2 ответа
@implementation ParallaxView
//Add Observe Method
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if([keyPath isEqualToString:@"contentOffset"]){
NSLog(@"contentOffset:%@", [change objectForKey:NSKeyValueChangeNewKey]);
}
}
@end
Попробуй заменить
objc_setAssociatedObject(self, ¶llaxKey, parallaxView, OBJC_ASSOCIATION_ASSIGN);
с
//Change to OBJC_ASSOCIATION_RETAIN_NONATOMIC
objc_setAssociatedObject(self, ¶llaxKey, parallaxView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
parallaxView
должно быть сильной ссылкой.
Проблема в коде
-(id)initWithFrame:(CGRect)frame
{
self = [self init];
[self setFrame:frame];
return self;
}
В приведенном выше коде self = [self init]; и [self setFrame:frame]; уйдет в рекурсию, даст сбой, сначала почините это, я думаю, это решит вашу проблему, должно быть так
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
а также загружает вид из пера с помощью
self = [[[NSBundle mainBundle]loadNibNamed:@"Parallex"
owner:self
options:nil] objectAtIndex:0];
этот код действительно плохая идея. Вы можете отослать ЭТО для этой задачи. Счастливое и чистое кодирование...