Objective c 目标C运行时参数绑定
我希望(在运行时)将一个参数绑定到一个函数,就像您在boost::bind中所做的那样-有点像下面这样:Objective c 目标C运行时参数绑定,objective-c,Objective C,我希望(在运行时)将一个参数绑定到一个函数,就像您在boost::bind中所做的那样-有点像下面这样: -(void)myFuncWithParameter:(NSString*)param { NSLog(param); } -(void)init { UIButton *helloButton = [UIButton buttonWithType:UIButtonTypeCustom]; [helloButton addTarget:self action:@sele
-(void)myFuncWithParameter:(NSString*)param {
NSLog(param);
}
-(void)init {
UIButton *helloButton = [UIButton buttonWithType:UIButtonTypeCustom];
[helloButton addTarget:self action:@selector(myFuncWithParameter:@"hello") forControlEvents:UIControlEventTouchUpInside];
}
所以。。。我(在运行时)将值@“hello”动态绑定到一个参数
显然,上面的语法不正确。有人知道这是否可行以及正确的语法吗
干杯,
尼克。简短的回答是否定的,或者至少不是那样 很长的答案是,在技术上可以构建类似于使用nsinvocation(和/或
forwardInvocation:
),在methodForSelector:中做一些聪明的事情,或者通过动态注册方法实现的东西,但这是非常棘手的,特别是如果您完全关心速度的话
如果我有一些代码,其中构建这样的curry方法是非常值得的,那么我会这样做(写在这篇评论中,未经测试)
显然,根据您的具体需要,您可以在不同的地方执行不同的操作,例如,您可以在forwardInvocation中由IMP惰性地执行操作,或者在实例中的dict中隐藏有关受管理的选择器的数据,而不只是将其管理到选择器名称中。简短的答案是否,或者至少不是在该级别 很长的答案是,在技术上可以构建类似于使用nsinvocation(和/或
forwardInvocation:
),在methodForSelector:中做一些聪明的事情,或者通过动态注册方法实现的东西,但这是非常棘手的,特别是如果您完全关心速度的话
如果我有一些代码,其中构建这样的curry方法是非常值得的,那么我会这样做(写在这篇评论中,未经测试)
显然,根据您的具体需求,您可以在其他地方做不同的事情,例如,您可以在forwardInvocation中由IMP惰性地执行,或者在实例中的dict中隐藏有关受管理的选择器的数据,而不仅仅是将其管理到选择器名称中。一般的答案是,目标操作机制只允许目标、发送者和接收发送者的消息;因此,如果需要访问数据,则必须从目标或发送方获取数据 一个选项是创建一个表示参数值、方法和对象绑定的类。此类将有一个调用对象上的方法并传递值的操作。使用此类的实例作为目标。这里有一个简单的例子:
@interface UnaryBinder : NSObject {
id target;
SEL selector;
id parameter;
}
@property id target;
@property SEL selector;
@property (retain) id parameter;
-(id)initWithTarget:(id)anObject selector:(SEL)aSelector param:(id)aParameter;
-(void)action:(id)sender;
@end
@implementation UnaryBinder
...
-(void)action:(id)sender {
[target performSelector:selector withObject:parameter];
}
@end
如果希望支持任意数量的参数,则需要使用NSInvocation(如Louis所述),而不是
performSelect:withObject
。当然,控件不会保留它们的目标,因此您需要某种方法来保留UnaryBinder。此时,您最好跳过特殊类,将数据存储在控件中,就像您在关于使用KVP的评论中提到的那样。或者,将动作分解到控制器类中,并使用该类的实例作为目标。在目标行动方面,UnaryBinder及其同类产品实际上没有任何优势。对于相关主题,谷歌“高阶消息传递”(higher order messaging)。一般的答案是,目标操作机制只允许目标、发送者和接收发送者的消息;因此,如果需要访问数据,则必须从目标或发送方获取数据
一个选项是创建一个表示参数值、方法和对象绑定的类。此类将有一个调用对象上的方法并传递值的操作。使用此类的实例作为目标。这里有一个简单的例子:
@interface UnaryBinder : NSObject {
id target;
SEL selector;
id parameter;
}
@property id target;
@property SEL selector;
@property (retain) id parameter;
-(id)initWithTarget:(id)anObject selector:(SEL)aSelector param:(id)aParameter;
-(void)action:(id)sender;
@end
@implementation UnaryBinder
...
-(void)action:(id)sender {
[target performSelector:selector withObject:parameter];
}
@end
如果希望支持任意数量的参数,则需要使用NSInvocation(如Louis所述),而不是
performSelect:withObject
。当然,控件不会保留它们的目标,因此您需要某种方法来保留UnaryBinder。此时,您最好跳过特殊类,将数据存储在控件中,就像您在关于使用KVP的评论中提到的那样。或者,将动作分解到控制器类中,并使用该类的实例作为目标。在目标行动方面,UnaryBinder及其同类产品实际上没有任何优势。对于相关主题,谷歌“高阶消息传递”。事后思考-我可以在按钮的图层[helloButton.layer setValue:@“hello”forKey:@“param1”]。。。然后在传递给被调用函数时引用该按钮。。。但这是一个相当丑陋的解决方案!事后考虑-我可以将KVP添加到按钮的层[helloButton.layer setValue:@“hello”forKey:@“param1”]。。。然后在传递给被调用函数时引用该按钮。。。但这是一个相当丑陋的解决方案!两个可能同样好的答案,但我在这里给出了它,因为它更容易理解和实现!N“当然,控件不保留它们的目标,所以需要某种方法来保持UnaryBinder。”这就是问题所在solution@user102008:这只是一个“问题”,因为在我的回答中没有明确提到存储UnaryBinder
,这就是我提到它的原因。此外,没有一个明确的解决方案的唯一原因是没有一个通用的解决方案,Nick没有给出关于他的具体设计的很多细节;UnaryBinder
的存储方式取决于设计需要。UnaryBinder
可以很容易地存储在控制器中(例如),但问题中没有提到一个特定的控制器用于。。。。并不是说你会看到这些评论,因为你没有一个。两个可能同样好的答案,但我在这里给出了它,因为它更容易理解和实现!N“当然,控件不保留它们的目标,所以需要某种方法来保持UnaryBinder。”这就是问题所在solution@user102008:这只是一个“问题”,因为存储UnaryBinder
并不明确