2010-05-12 22 views
5

Tôi có quan điểm rằng khi nhận được nhấn đúp, gửi thông báo đến bộ điều khiển gốc, người này sẽ loại bỏ và nhả chế độ xem.Đối tượng được phân giải nhận thông báo nhận dạng UIGestureRecognizer

Vấn đề là sau khi chế độ xem được phát hành, nó sẽ nhận được một sự kiện GestureRecognizer bị trì hoãn khác.

Sau đây là các thông tin từ 'cụ':

Category  Event Type RefCt Timestamp Address  Size Responsible Library Responsible Caller 
UIScrollView Zombie   -1 00:06.166 0x55496a0 0     UIKit -[UIGestureRecognizer _updateGestureWithEvent:] 


    0 CoreFoundation ___forwarding___ 
    1 CoreFoundation _CF_forwarding_prep_0 
    2 UIKit -[UIGestureRecognizer _updateGestureWithEvent:] 
    3 UIKit -[UIGestureRecognizer _delayedUpdateGesture] 
    4 UIKit _UIGestureRecognizerUpdateObserver 
    5 UIKit _UIGestureRecognizerUpdateGesturesFromSendEvent 
    6 UIKit -[UIWindow _sendGesturesForEvent:] 
    7 UIKit -[UIWindow sendEvent:] 
    8 UIKit -[UIApplication sendEvent:] 
    9 UIKit _UIApplicationHandleEvent 
    10 GraphicsServices PurpleEventCallback 
    11 CoreFoundation CFRunLoopRunSpecific 
    12 CoreFoundation CFRunLoopRunInMode 
    13 GraphicsServices GSEventRunModal 
    14 GraphicsServices GSEventRun 
    15 UIKit UIApplicationMain 
    16 ipadapp main /Users/test/Projects/app/ipadapp/main.m:7 
    17 ipadapp start 

UIScrollView dường như sẽ được phát hành vào đúng thời điểm.

Câu hỏi là tại sao sự kiện cử chỉ bổ sung này đến.

+0

Mọi phản hồi kể từ đó? Tôi có cùng một vấn đề – CedricSoubrie

Trả lời

0

Cử chỉ bị trì hoãn, theo định nghĩa, được gửi sau một chút chậm trễ. Điều này (UIScrollViewDelayedTouchesBeganGestureRecognizer) được sử dụng để đảm bảo pinch và cử chỉ pan có được ưu tiên cao hơn.

Trình nhận dạng cử chỉ sẽ không giữ lại trạng thái của nó để tránh chu kỳ lưu giữ. Do đó, khi trình nhận dạng này kích hoạt, nó sẽ gửi đến một khung nhìn được phân phối lại.

Bạn có thể trì hoãn -release chế độ xem (ví dụ: -performSelector:withObject:afterDelay:). Hoặc thay vì xóa chế độ xem, bạn chỉ có thể đặt chế độ xem hidden.

+0

Cảm ơn câu trả lời. Tôi tìm thấy cả hai lựa chọn của bạn để âm thanh hơi giống như cách giải quyết xấu (không có hành vi phạm tội ...) - không phải là có một cách để nói với công nhận cử chỉ để xóa tất cả các tin nhắn đang chờ xử lý? Tôi đã thử gọi 'removeTarget' trên trình nhận dạng cử chỉ và 'removeGestureResognixer' trên chế độ xem nhưng vẫn không có may mắn. –

+0

@LK: Bạn đã thử đặt '.gestureRecognizers' thành nil? – kennytm

+0

Trên thực tế đã không giải quyết nó ... Ngay cả với một sự chậm trễ tôi nhận được điều này. –

7

Tôi không biết nếu tôi có chính xác cùng một vấn đề nhưng đây là cách tôi đã làm cho tôi:

1- Enable Zombie mode trong Xcode để có được một thông điệp chính xác để chắc chắn bạn đang nhìn vào đúng địa điểm. Sau đó bạn sẽ nhận được một thông điệp như thế này: [Khái quát gestureRecognizerFailed:]: Thông điệp gửi đến dụ deallocated 0x53d6d00

2- Bây giờ bạn biết vấn đề chính xác, cử chỉ tắt nhật trên đối tượng này trước khi tháo nó:

// I have to remove the gestures, because a GesturerecongizerFailed can arrive after the view has been deallocated 
    for (UIGestureRecognizer* gesture in self.overView.gestureRecognizers) { 
     NSLog(@"Desactive un gesture"); 
     gesture.delegate = nil ; 
     gesture.enabled = NO; 
    } 
    // Remove the view from the display 
    [self.overView removeFromSuperview]; 
    self.overView = nil; 

Điều này sẽ thực hiện thủ thuật.

[EDIT] Một giải pháp khác phù hợp với tôi: không sử dụng 'autorelease' cho công cụ nhận dạng cử chỉ. Trong hầu hết trường hợp, bạn có thể trực tiếp phát hành trình nhận dạng sau khi thêm nó vào một khung nhìn.

+0

Nếu sử dụng chúng dưới dạng IBOutlets, hãy đảm bảo chúng yếu và sau đó không có thuộc tính sau khi bạn sử dụng xong nếu cần. Tương tự như chỉnh sửa ở trên nhưng có thể không rõ ràng đối với một số. – cynistersix

0

là có bất cứ điều gì sai trái với chỉ đơn giản là làm điều này:

if (gestureRecognizer) { 
    if ((touch.view == UIButtonTypeCustom)) { 
     return NO; 
    } 
    return YES; 
} else return NO; 
2

Dường như nhận dạng cử chỉ của bạn đang gửi một callback để điều khiển của bạn sau khi điều khiển của bạn đã được deallocated. Đảm bảo bạn xóa trình nhận dạng cử chỉ của mình khỏi chế độ xem bạn đã gắn nó vào trước khi bạn giải quyết bộ điều khiển của mình.

Trong lớp điều khiển của bạn, bạn có thể thiết lập một cái gì đó cử chỉ nhận dạng của bạn như thế này:

- (void)loadView { 
    [super loadView]; 
    _view = [[UIView alloc] init]; 
    _doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_handleDoubleTap:)]; 
    [_view addGestureRecgonizer:_doubleTapGestureRecognizer]; 
} 

Vì vậy, hãy chắc chắn rằng bạn loại bỏ các nhận dạng cử chỉ trong phương pháp dealloc của bộ điều khiển của bạn:

- (void)dealloc { 
    [_view removeGestureRecognizer:_doubleTapGestureRecognizer]; 
    [_doubleTapGestureRecognizer release]; 
    [_view release]; 
    [super dealloc]; 
} 
0

Dưới đây là một giải pháp rõ ràng về cách tôi giải quyết nó .. hãy đảm bảo phát hành chế độ xem thực tế của bạn.Quan điểm của tôi có một loạt các bản xem trước mà tôi đã phát hành nhưng tôi đã không tiết lộ quan điểm thực tế của mình. Sau khi tôi đã làm, chương trình là tốt.

Các vấn đề liên quan