将 Objective-C 协议委托作为参数传递

Posted

技术标签:

【中文标题】将 Objective-C 协议委托作为参数传递【英文标题】:Passing an objective-c protocol delegate as a parameter 【发布时间】:2015-08-14 02:31:30 【问题描述】:

当我将objective-c 协议作为参数传递时,当该委托用于触发其方法之一时,该方法不会触发。

我正在使用来自Paypal ios SDK 的委托,定义如下:

@protocol PayPalPaymentDelegate <NSObject>
    - (void)payPalPaymentDidCancel:(PayPalPaymentViewController *)paymentViewController;
@end

我有一个实现协议的 UIViewController:

//simpleviewcontroller.h
@interface SimpleViewController : UIViewController<PayPalPaymentDelegate>

以及如下的方法签名:

// HelperFunctions.m
+ (void) doSomething: (id<PayPalPaymentDelegate>)paypalDelegate

    // the selector 'payPalPaymentDidCancel' DOES fire
    [paypalDelegate performSelector:@selector(payPalPaymentDidCancel:) withObject:self]



// called from simpleviewcontroller.m that implements PayPalPaymentDelegate
[HelperFunctions doSomething: self]

问题是paypal返回结果时,并没有触发delegate:

// code inside of the 'success' block of an AFNetworking call
PayPalPaymentViewController *paymentViewController;
paymentViewController = [[PayPalPaymentViewController alloc] initWithPayment:payment    
                                                             configuration:paypalConfiguration   
                                                             delegate:paypalDelegate];

此处传递给“delegate”的 paypalDelegate 永远不会由 paypal 触发。而如果从 simpleviewcontroller.m 完成而不是通过方法 doSomething 会触发它

【问题讨论】:

我认为你也应该传递 SimpleViewController 因为委托方法也需要视图控制器。它在 SimpleViewController 上工作,因为你传递了“他”,但它不工作,因为你传递了“HelperFunctions”对象。 (哦等等,代理!只需使用 paypalDelegate 而不是 self。) 在你写[paypalDelegate performSelector:@selector(payPalPaymentDidCancel:) withObject:self];的那一行,self是指什么?毕竟,它在类方法中。 【参考方案1】:

一旦您创建了paymentViewController,您是否还在某处保留paypalDelegatePayPalPaymentViewController 仅保留对委托的弱引用,因此如果没有,它将在创建 PayPalPaymentViewController 的范围末尾由 ARC 释放(因此不会触发任何方法)。

【讨论】:

我根本没有将 paypalDelegate 存储在任何变量中,只是将 Self 传递给方法 doSomething。我应该创建一个强变量并将 paypalDelegate 放入其中吗?请注意,在方法 does 中使用 performSelector 可以正常工作,所以这是否表明委托的引用没有丢失? 是在doSomething: 方法中创建PayPalPaymentViewController 的代码吗?虽然我假设您是视图控制器(委托)在视图控制器层次结构中,所以可能没有被释放?在delegate对象的dealloc方法里放一个log,检查一下是不是被释放了。

以上是关于将 Objective-C 协议委托作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章

协议作为 swift 冲突中的参数类型

C# 将委托作为参数传递

将成员函数作为委托参数传递

在 Swift 上委托 Objective-C 协议

如何在 Objective-C 中将 BOOL 变量作为参数传递?

C# 再次理解委托事件与函数作为参数