2015-04-30 33 views
0

我將字典值中的目標和操作傳遞給UIButtons。這工作正常,除非我嘗試並傳遞一個NSInvocation/invoke對。對於NSInvocation/invoke對,addTarget失敗

// |self| is a member of |MyClass|, which declares selector |test| 

NSDictionary *button1Data = @{ @"selectorString" : NSStringFromSelector(@selector(test)), 
           @"target" : self }; 

[button1 addTarget:button1Data[@"target"] 
      action:NSSelectorFromString(button1Data[@"selectorString"]) 
    forControlEvents:UIControlEventTouchUpInside]; 

// button1 executes target fine 

NSInvocation *testInvocation = [NSInvocation invocationWithMethodSignature:[MyClass instanceMethodSignatureForSelector:@selector(test)]]; 
    testInvocation.selector = @selector(test); 
    testInvocation.target = self; 
    [testInvocation retainArguments]; 

NSDictionary *button2Data = @{ @"selectorString" : NSStringFromSelector(@selector(invoke)), 
             @"target" : testInvocation }; 

[button2 addTarget:button2Data[@"target"] 
      action:NSSelectorFromString(button2Data[@"selectorString"]) 
    forControlEvents:UIControlEventTouchUpInside]; 

// button2 executes gives exceptions 

button2的異常沒有寄存器轉儲。

我在忽略什麼?

+0

你說「工作正常」,但不要說它不工作。 – newacct

回答

2

addTarget:action:forControlEvents:不保留目標。你的NSInvocation對象是在函數內部本地創建的,當沒有人強有力地引用它時,它將在函數結束時被釋放。然後按鈕會發送一條消息給一個釋放的實例,導致各種不好的事情。

+0

這有真相的悲傷環!如果可行,我將在MyClass中保留NSInvocation。謝謝! – Thompson

+1

@Thompson:或者您可以將該調用添加爲按鈕的保留關聯對象 – newacct

+0

我會給出一個外觀,謝謝 – Thompson