我有一个以表单形式呈现的模态视图控制器,它具有委托协议。我正在实现该协议并在展示之前分配一个委托,但即使该属性是强引用,它仍然会丢失。欢迎提供任何可能的原因。谢谢!
以下是该属性声明,使用了 strong 关键字。
这是SDStoreViewController的viewDidLoad方法。它已经失去了它的代理。
以下是该属性声明,使用了 strong 关键字。
@protocol SDStoreViewDelegate <NSObject>
// Methods
@end
@interface SDStoreViewController : UIViewController
@property (strong, nonatomic) id <SDStoreViewDelegate> delegate;
@end
这里是创建对象并设置委托的地方。
SDStoreViewController *store = [[SDStoreViewController alloc] init];
[store setDelegate:self];
NSLog(@"1 %@",store.delegate); // Returns Object as expected
[self presentViewController:store animated:YES completion:^{
NSLog(@"3 %@",store.delegate); // Returns Object as expected
}];
NSLog(@"4 %@",store.delegate); // Returns Object as expected
这是SDStoreViewController的viewDidLoad方法。它已经失去了它的代理。
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"3 %@",_delegate); // Returns NULL
}
这是因为在调用委托时,如果它不是NULL,则会被解除。
- (void)dismiss:(id)sender
{
NSLog(@"5 %@",_delegate); // Returns NULL
[self.delegate aMethod];
}
更新
我已经使用了weak
和strong
引用。我也使用了self.delegate
和_delegate
来访问属性。作为一个观察点,aMethod
回调没有传递,这促使我进行侦查工作以找出它在哪里丢失。
viewDidLoad
中查看它们是否相同? - omz-viewDidLoad
不可能显示null,而演示完成块显示委托。-viewDidLoad
将在调用该完成块之前被调用,因此发生了其他事情(可能是您代码中的掩码变量或其他任何事情)。您需要展示您正在使用的真实、精确的代码。 - Jason CocoviewDidLoad
将在presentViewController:...
的完成块之前被调用,这意味着委托首先是nil
,但后来以某种方式设置为正确的值,而你并没有做任何事情,只是稍后又变成了nil
。顺便说一下,你应该在日志中使用不同的数字,因为现在你无法区分两个“3”日志。 - omz-viewDidLoad
中,则表示您正在使用两个不同的视图控制器对象实例或已掩盖了 ivar。如果它在完成块中打印为 nil,则可以假设它被某种方式取消设置。在-viewDidLoad
中打印 self 的地址和控制器的地址。它们是否不同? - Jason Coco