我實現了一個照片編輯應用程序,其中我有一個攝像頭拍攝的圖像,一個是輸出圖像,我是在拍攝圖像旁邊顯示的。每當我改變我捕捉的圖像縮放或旋轉,然後我想通知這個更改outputImage。對於這個塞納里奧我寫下面的代碼,KVO機制拋出錯誤?
-(void)imageCapturedByCameraAPI:(UIImage *)theCapturedImage{
[[arOverlayVC view] removeFromSuperview];
capturedImageView.image = theCapturedImage;
[self.view addSubview:imageEditorView];
rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotatePiece:)];
[capturedImageView addGestureRecognizer:rotationGesture];
**//KVO added for rotation**
[capturedImageView addObserver:self forKeyPath:@"transform.rotate" options:NSKeyValueObservingOptionNew context:NULL];
pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scalePiece:)];
[pinchGesture setDelegate:self];
[capturedImageView addGestureRecognizer:pinchGesture];
**//KVO added for scaling**
[capturedImageView addObserver:self forKeyPath:@"transform.scale" options:NSKeyValueObservingOptionNew context:NULL];
}
- (void)rotatePiece:(UIRotationGestureRecognizer *)gestureRecognizer {
[self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
[gestureRecognizer view].transform = CGAffineTransformRotate([[gestureRecognizer view] transform], [gestureRecognizer rotation]);
[self editedImage];
[gestureRecognizer setRotation:0];
}
}
- (void)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer {
if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
lastScale = [gestureRecognizer scale];
}
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];
const CGFloat kMaxScale = 2.0;
const CGFloat kMinScale = 1.0;
CGFloat newScale = 1 - (lastScale - [gestureRecognizer scale]);
newScale = MIN(newScale, kMaxScale/currentScale);
newScale = MAX(newScale, kMinScale/currentScale);
CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
[gestureRecognizer view].transform = transform;
lastScale = [gestureRecognizer scale];
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
// if the gesture recognizers are on different views, don't allow simultaneous recognition
if (gestureRecognizer.view != otherGestureRecognizer.view)
return NO;
// if either of the gesture recognizers is the long press, don't allow simultaneous recognition
if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] || [otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]])
return NO;
return YES;
}
- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
UIView *piece = gestureRecognizer.view;
CGPoint locationInView = [gestureRecognizer locationInView:piece];
CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview];
piece.layer.anchorPoint = CGPointMake(locationInView.x/piece.bounds.size.width, locationInView.y/piece.bounds.size.height);
piece.center = locationInSuperview;
}
}
現在我的觀察方法是,
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if(object == capturedImageView && ([keyPath isEqualToString:@"transform.rotate"] || [keyPath isEqualToString:@"transform.scale"])) {
NSLog(@"KVO detected");
}
}
我發現了以下錯誤,
一個實例類NSConcreteValue的0x189f40被同時 鍵釋放價值觀察員仍然登記在案。觀察信息 被泄露,甚至可能被錯誤地附加到其他一些對象。在NSKVODeallocateBreak上設置一個斷點,在 調試器中停止。下面是當前觀測信息: (背景:爲0x0,物業:0x189ff0>
一個實例類NSConcreteValue的0x188cb0被釋放,而 鍵值觀察家仍用它註冊的觀測信息 被泄露,甚至可能誤成了。連接到其他一些 對象設置上NSKVODeallocateBreak斷點停在這裏的 調試下面是當前觀測信息:。 (背景:爲0x0,物業:0x188d80>
*終止應用程序由於未捕獲的異常 「N SInternalInconsistencyException',原因:'無法更新 關鍵路徑 「transform.scale」的觀察者,很可能是因爲密鑰「變換」的 值已更改,而沒有發送適當的KVO 通知。檢查UIImageView 類的KVO合規性。'
有更多的問題與您的代碼,例如不檢查上下文。在這個答案中,我已經編譯瞭如何獲得KVO的一些經驗法則:http://stackoverflow.com/questions/9231896/kvo-how-to-check-if-an-object-is-an-observer – 2013-02-26 09:30:33