【问题标题】:Objective-C self.delegate is null after being setObjective-C self.delegate 设置后为空
【发布时间】:2015-05-17 05:43:24
【问题描述】:

我为 UIView 设置了一个非常简单的委托。但是,当我尝试这样做时:

if ([self.delegate respondsToSelector:@selector(selectedPlayTrailer:)]){
    [self.delegate selectedPlayTrailer:self];
}

我的 self.delegate 为空。我检查了设置为委托的类是正确的:

- (void)setDelegate:(id<MyViewDelegate>)delegateClass
{
    // Whether I overwrite this method or not, it's still null.
    NSLog(@"%@", delegate);
    _delegate = delegateClass;
}

而且它是正确的。但是当它在我的 IBAction 中被调用时 - 它是空的。

编辑:澄清一下,我只是将其放入以查看传入的内容。如果我不覆盖此方法,它仍然为空。

我的代码:

MyView.h

#import <UIKit/UIKit.h>

@class MyView;

@protocol MyViewDelegate <NSObject>
@optional
- (void) myDelegateMethod:(MyView *)sender;
@end

@interface MyView : UIView

@property (nonatomic, weak) id <MyViewDelegate> delegate;

- (IBAction)myButton:(id)sender;

@end

MyView.m

@implementation MyView

@synthesize delegate;

- (id)init
{
    if (!(self = [super init])) return nil;

    NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"MyView"
                                                          owner:self
                                                        options:nil];

    return self;
}

- (IBAction)myButton:(id)sender
{
    // NOTE: Here, self.delegate is null
    if ([self.delegate respondsToSelector:@selector(myDelegateMethod:)]){
        [self.delegate myDelegateMethod:self];
    }
}

@end

MyCollectionViewCell.m

#import "MyCollectionViewCell.h"
#import "MyView.h"

@interface MyCollectionViewCell() <MyViewDelegate>
@property (nonatomic, strong) MyView *myView;
@end

@implementation MyCollectionViewCell

@synthesize myView;

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self){
        [self setup];
    }

    return self;
}

- (void)setup
{
    self.myView = [MyView new];
    self.myView.frame = CGRectMake(0,0,self.bounds.size.width, self.bounds.size.height);
    self.myView.alpha = 0.0;
    self.myView.layer.cornerRadius = 5.0f;
    self.myView.layer.masksToBounds = YES;
    self.myView.delegate = self;

    [self addSubview:self.myView];
}

// The delegate method
- (void)myDelegateMethod:(MyView *)sender
{
    NSLog(@"This is never called...");
}

@end

【问题讨论】:

  • 代理是否有可能被释放?尝试将委托属性从弱更改为分配并打开僵尸 - 看看你是否收到错误。
  • initWithFrame 被调用?
  • @Paulw11 尝试但没有错误,仍然为空。还尝试将其设置为强(我知道您通常不应该使用委托属性),但这也无济于事。
  • @Selvin 是的。视图已正确添加,没有错误,但在我调用 IBAction 时委托已失效。
  • 尝试将 ViewController 设置为委托而不是 collectioviewcell

标签: ios objective-c xcode delegates


【解决方案1】:

将视图控制器设置为 MyView 对象的委托,而不是集合视图单元。

在您的视图控制器中,在数据源方法中

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath

做这样的事情。

cell.myView.delegate = self;

更新

正如观察到的,问题在于分配UIView 子类。将视图初始化为

self.myView = [MyView new];

由于某种原因不起作用。要正确分配视图,可以使用following approach

 self.myView = [[[NSBundle mainBundle]
        loadNibNamed:@"MyView"
        owner:self options:nil]
         firstObject];

【讨论】:

  • 好的,试过了,但得到了同样的结果。它是空的。当我覆盖设置器时,它说 是被设置为委托的那个。但是当我运行应用程序并单击按钮触发 IBAction self.delegate 仍然是(null)
  • MyView init 方法可能是错误的。它可以创建 2 个实例
  • stackoverflow.com/a/15406012/569497 使用这种方法来初始化你的子类
  • @Matt 我很高兴知道它有帮助!我已经更新了答案:)
  • 为了分配自定义 UIView 子类,我一直使用[[[NSBundle mainBundle] loadNibNamed:@"nibname" owner:self options:nil] firstObject]; 方法。对于UIViewController 子类,[ViewController new] 有效。但不适用于UIView 子类。确实很奇怪!
【解决方案2】:

MyCollectionViewCell添加这个:

- (void)dealloc
{
    NSLog(@"MyCollectionViewCell dealloc called")
}

delegate 是一个弱引用。因此,如果设置为delegate 的实例被释放,它将变为nil。上述的目的是确认这种情况正在发生。

为什么会发生这种情况?如果没有任何东西保持对MyCollectionViewCell 实例的强引用,那么它将被释放。

理想情况下,您还希望将NSLog 添加到myButtonPressed:。如果您NSLog'd 代表的设置也将是有益的。所以你的输出可能是这样的:

Delegate set
MyCollectionViewCell dealloc called <- this would indicate that the delegate becomes nil based on the instance being released
myButtonPressed: hit

鉴于您提供的信息量,这是一个可行的理论。

【讨论】:

  • 感谢您的建议。我刚刚尝试过,但collectionviewcell 没有被释放。设置单元的代码也不是什么时髦的东西。这只是通常的 dequeueReusableCellWithReuseIdentifier
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
  • 2011-02-06
  • 1970-01-01
相关资源
最近更新 更多