对 addTarget:action:forControlEvents 的 addTarget 指针行为感到困惑:
Posted
技术标签:
【中文标题】对 addTarget:action:forControlEvents 的 addTarget 指针行为感到困惑:【英文标题】:Confused about addTarget pointer behavior for addTarget:action:forControlEvents: 【发布时间】:2014-06-22 06:14:25 【问题描述】:我有一个带有委托属性的 UIView 子类。在init方法中,我设置了
self.delegate = nil.
视图也有一个按钮,所以在init方法中,我也设置了按钮的target为self.delegate,也就是nil:
[myButton addTarget:self.delegate action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside]
在设置我的 UIView 子类的 UIViewController 中,我调用 UIView 中的一个方法,将 UIView 的 self.delegate 设置为 UIViewController。当我单击按钮时,似乎反映了目标的变化。
我想知道这最终是如何工作的,因为我的理解是 addTarget:action:forControlEvents 将 id 作为目标,并且指针应该在 Obj-C 中按值传递。因此,我很困惑为什么在调用 addTarget 方法之后更新了最初的 nil 值指针。
【问题讨论】:
目标,正如您通过将其设置为self.delegate
所看到的那样,是一种引用类型,因此表现为一个引用类型。我不确定您所说的按值传递指针是什么意思,因为指针就是我们所说的引用。使用类型创建指针是我们获取引用类型的方式,id
(目标是什么)就是一个例子。
我的理解是指针是它们所引用的数据对象的内存地址。当您将指针作为方法参数传递时,您正在传递此内存地址的值。但是,这并不能解释为什么更改原始 UIView 类中的指针值应该更改传递给 addTarget 方法的指针值。似乎这些情况通常使用指向指针的 ** 指针。
我明白你的意思,确实你是对的。查看该方法的文档,这是目标If this is nil, the responder chain is searched for an object willing to respond to the action message
定义的一部分。所以这可能正在发生,因为该视图是唯一可以响应 buttonAction
的子视图
谢谢,这就解释了。
【参考方案1】:
这样做的正确方法是为您的视图声明一个协议,该协议将委托按钮的点击操作,即
YourView.h
@class 你的视图; @protocol YourViewDelegate @选修的 - (void)customView:(YourView *)view didSelectButton:(id)button; @结尾 @interface YourView : UIView //... @property (weak, nonatomic) idYourView.m
@interface 你的视图() @结尾 @执行 - (id)初始化 if (self = [super init]) //... [自我设置]; 回归自我; - (void)awakeFromNib //... // 从情节提要创建此视图时设置逻辑 [自我设置]; -(无效)设置 [myButton addTarget:self 动作:@selector(buttonTapped :) forControlEvents:UIControlEventTouchUpInside]; - (void)buttonTapped:(id)sender if (self.delegate && [self.delegate respondsToSelector:@selector(customVIew:didSelectButton)] [self.delegate customView:self didSelectButton:sender]; @结尾然后,在您的视图控制器中实现 YourViewDelegate 类别:
@interface YourViewController() //... @结尾 @执行 - (void)viewDidLoad [超级视图DidLoad]; //... self.yourView.delegate = self; //... - (void)customView:(YourView *)view didSelectButton:(id)button //做你的事 @结尾【讨论】:
感谢您的解释。这是非常有用的。你知道为什么改变 self.delegate 的值也会改变 addTarget 方法引用的值,即使我调用 addTarget 方法时 self.delegate 的值是 nil 吗?【参考方案2】:Objective-C
使用Dynamic binding
。要调用的方法是在运行时而不是在编译时确定的。这就是为什么它也被称为后期绑定。
参考链接 - https://developer.apple.com/library/ios/documentation/general/conceptual/DevPedia-CocoaCore/DynamicBinding.html
那么什么是委托以及调用哪个方法是在运行时定义的。
【讨论】:
Dynamic binding
真的只是一种花哨的说法,Objective-C 使用指针来做所有事情吗?以上是关于对 addTarget:action:forControlEvents 的 addTarget 指针行为感到困惑:的主要内容,如果未能解决你的问题,请参考以下文章