2013-02-12 45 views
0

我創建一個UITapGesture,其目標不是當前對象。之後,當點擊時,應用程序崩潰。未保留UITapGesture目標(使用ARC)

視圖控制器的.h:

@interface ViewController : UIViewController 
{ 
    IBOutlet UIImageView *iv; 
} 
@end 

視圖控制器的.c:

#import "ViewController.h" 
#import "Target.h" 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    Target *t = [[Target alloc] init]; 
    UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:t action:@selector(gestureDone:)]; 
    [iv addGestureRecognizer:tgr]; 
    [iv setUserInteractionEnabled:YES]; 
} 

@end 

Target.h:

@interface Target : NSObject 

- (void)gestureDone:(UIGestureRecognizer *)gr; 

@end 

Target.c:

@implementation Target 

- (void)gestureDone:(UIGestureRecognizer *)gr 
{ 
    NSLog(@"Gesture!"); 
} 

@end 

(我的XIB文件只包含一個圖像...) 當點擊圖像時,它崩潰。例如,如果我添加一個實例變量Target * t到我的視圖控制器(並刪除viewDidLoad中的本地聲明),則不會出現問題。當不這樣做時,我重寫了Target中的dealloc,在那裏放了一個NSLog,並且看到只要viewDidLoad完成執行,Target對象就是fred。

我做錯了什麼,還是有些問題? (通常我不會遇到這個問題,因爲我使用initWithTarget:self ...)。

+0

請問您可以添加崩潰日誌嗎? – 2013-02-13 00:05:10

回答

7

UIGestureRecognizer不保留其目標。大多數採用目標/動作對的對象不保留其目標。這在Cocoa Fundamentals Guide/Communicating with Objects/The Target-Action Mechanism/The Target中提到:

控制對象不會(也不應該)保留它們的目標。但是,發送操作消息的控件的客戶(通常是應用程序)負責確保其目標可用於接收操作消息。要做到這一點,他們可能不得不在內存管理環境中保留目標。此預防措施同樣適用於代表和數據源。

你需要確保目標保留一些其他的方式,比如通過在ViewController的實例變量存儲到t參考。

+0

謝謝,這就是我想出的。你有任何官方的參考嗎?我在發佈之前搜索過,無法找到任何說明它不會保留的內容。 – user1532080 2013-02-13 14:11:01

+0

我已經更新了我的答案。 – 2013-02-13 22:21:09

0

將目標t的實例變量添加到您的ViewController課程中並使其更強大。這種方式留在記憶中。