2013-02-26 84 views
0

我實現了一個照片編輯應用程序,其中我有一個攝像頭拍攝的圖像,一個是輸出圖像,我是在拍攝圖像旁邊顯示的。每當我改變我捕捉的圖像縮放或旋轉,然後我想通知這個更改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合規性。'

+0

有更多的問題與您的代碼,例如不檢查上下文。在這個答案中,我已經編譯瞭如何獲得KVO的一些經驗法則:http://stackoverflow.com/questions/9231896/kvo-how-to-check-if-an-object-is-an-observer – 2013-02-26 09:30:33

回答

1

的錯誤消息說

類的一個實例被釋放,而鍵值觀察家仍用它

你需要capturedImageView之前刪除的觀察註冊使用removeObserver:forKeyPath:context:被釋放

確保您具有註冊/取消註冊的計數或不打破KVO。你想知道更多關於志願

我,這個環節是有幫助的:http://www.mikeash.com/pyblog/key-value-observing-done-right.html

和第2部分:http://www.mikeash.com/pyblog/friday-qa-2012-03-02-key-value-observing-done-right-take-2.html

+0

你的意思是我想創建UIImageview的capturedImageView的子類,在那裏我想實現delloc方法並刪除我的觀察鍵。不要使用ARC如此delloc方法工作在ARC的UIImageview的子類? – Tirth 2013-02-26 09:51:58

1

弧只處理內存NSObject的&有限公司,其他一切(例如韓國國際志願者組織或網絡連接或文件寫入),你需要手動清理

覆蓋 - 觀測的變化時(無效)的dealloc爲

- (void)dealloc { 
    [capturedImageView removeObserver:self forKeyPath:@"transform.scale"]; 
} 
+0

你的意思是我想創建UIImageView的capturedImageView的子類,在那裏我想實現delloc方法並刪除我的觀察鍵。不要使用ARC如此delloc方法工作在ARC的UIImageview的子類? – Tirth 2013-02-26 09:52:21

+0

沒有ADDS觀察者的類,將其刪除。所以在你的VC的dealloc方法中,你用captureImageView完成了,你移除了觀察者 – 2013-02-26 10:18:54