【问题标题】:IOS delegate function not getting calledIOS委托函数没有被调用
【发布时间】:2015-03-18 03:59:15
【问题描述】:

免责声明:我在谈论代表时使用的术语可能有点不妥。

虽然我发现了一些有趣的行为,但我已经调试了几个小时了,但还没有得到任何结果。基本上我有一个带有自定义 NSObject (NSO) 实例作为属性的 UIViewController (VC)。我在 NSO 对象中创建了一个委托,以便它可以在 VC 中通话/调用函数。我以前这样做过,所以我认为没问题,但是当我尝试从 NSO 对象调用委托函数时,VC 没有收到调用。

这是我的 NSO 类界面

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <Parse/Parse.h>
#import <MobileCoreServices/MobileCoreServices.h>

@protocol ServerDBDelegate <NSObject>

@required
- (void) func;

@end


@interface ServerDB : NSObject <CLLocationManagerDelegate>

@property (nonatomic, retain) id<ServerDBDelegate> delegate;


@end

NSO 对象使用 CoreLocation,我从 CoreLocation 委托函数之一调用 VC 委托函数,特别是...

 -(void)locationManager: didUpdateLocations: {
      [self.delegate func];
 }

如果这令人困惑,请发表评论,我会澄清。

由于 VC 从未收到我在这一行中放入上述函数的调用。

NSLog(self.delegate == nil ? @"Nil" : @"Not nil");

而且每次都会打印“Nil”,所以我认为我没有正确设置我的代表。经过更多调试后,我仍然认为我正确地执行了委托,所以我重写了委托的设置器,以查看它是否在某个时候被正确设置。

- (void) setDelegate:(id<ServerDBDelegate>)delegate {
    _delegate = delegate;
    NSLog(self.delegate == nil ? "Nil2" : "Not Nil2");
}

当 setter 被调用时,它输出了“Not Nil2”,然后一瞬间我看到了 CoreLocation 委托函数的输出“Nil”。所以我认为我最初正确设置了委托,但在某些时候它被覆盖为零。好的,我的最后一步。

- (void) setDelegate:(id<ServerDBDelegate>)delegate {
    _delegate = delegate;
    [self performSelector:@selector(test) withObject:self afterDelay:3];
}

- (void) test {
   NSLog(self.delegate == nil ? "Nil2" : "Not Nil2");
}

-(void)locationManager: didUpdateLocations: {
    NSLog(self.delegate == nil ? "Nil" : "Not Nil");
    [self test];
}

重要的是要知道,locationManager 函数每秒会被调用几次。所以当我运行它时,我会看到这个输出

Nil
Nil2
Nil
Nil2
Nil
Nil2
Nil
Nil2
Not Nil2
Nil
Nil2

所以看起来委托没有设置,但是当我在延迟后从设置器调用 test: 时,它仍然设置,但仅在该函数的范围内。我真的不知道如何进行或错误可能在哪里。提前感谢您的帮助。

【问题讨论】:

  • 您在哪里/如何声明您的 _delegate?
  • 我会将其添加为编辑。
  • 您作为代表分配了什么?该类是否符合您的委托?
  • VC 的声明如下所示:@interface ViewBarsViewController : UIViewController 我将 NSO 实例委托设置为 UIViewController
  • 你是怎么调用setDelegate方法的?

标签: ios delegates core-location


【解决方案1】:

我认为您误解了代表的工作方式。 但在继续之前我有一个问题:你没有使用 ARC 吗?我看到你在你的委托属性上使用了retain

无论哪种方式,如果您将retain 用于您的委托属性(即ARC 下的strong)而不是weak,您将创建一个保留循环

现在回到你的问题:

  1. 您声明协议和委托的方式没问题(除了在 ARC 下它应该是分配的或弱的)。

  2. 这个方法在我看来几乎没问题:

    -(void)locationManager: didUpdateLocations: { [self.delegate func]; }

但作为一种好的做法,您应该始终检查您的代表是否为respondsToSelector。所以在[self.delegate func] 后面加上一个if 语句,如下所示:if ([self.delegate respondsToSelector:@selector(func)]){self.delegate func];}

  1. 当你想符合一个委托时,在应该符合它的类中,你必须将ServerDBDelegate 添加到它的接口声明中,如下所示:

    @interface myClass: superclass &lt;ServerDBDelegate&gt;

  2. 在您声明您的类应符合 ServerDBDelegate 后,您必须通过调用以下内容成为该类的委托:

[[ServerDB sharedManager] setDelegate: self]; //example of a singleton class setDelegate call.

或者在符合 ServerDBDelegate 的类中有一个 ServerDB 属性(非原子,强),在你的类中的某个地方实例化它(viewDidLoad 是一个很好的候选者)或者做一个惰性实例化并成为 ServerDB 的委托像这样的类:

头文件(.h):

@interface myClassViewController: UIViewController <ServerDBDelegate>
@end

实施文件 (.m)

    @interface myClassViewController ()
    @property (nonatomic, strong) ServerDB *dbInstance; //hold a strong reference to the ServerDBClass
    @end

    @implementation myClassViewController

    //lazy instantiation
    - (ServerDB *)dbInstance {
      if (_dbInstance) {return _dbInstance;}
      _dbInstance = [[ServerDB alloc] init];
      return _dbInstance;
    }

    - (void)viewDidLoad {
       [super viewDidLoad];
       self.dbInstance.delegate = self; //here you make myClassViewController a delegate of your ServerDB class
    }

    //add and define the required method from your delegate protocol
    - (void)func {
      NSLog(@"ServerDB called me: %@",NSStringFromSelector:@selector(_cmd));
    }
    @end

现在,每当您在 ServerDB 类中执行调用委托“func”方法的操作时,委托都会调用您在 myClassViewController 中定义的“func”方法。

【讨论】:

  • 老实说,我认为我做了以上所有事情。我在委托声明中将保留更改为分配,但没有效果。
  • 您是否像我在 viewDidLoad 或 segue 中所做的那样,通过将 self 分配给 ServerDBDelegate 来使您的 ViewController 类成为您的 ServerDB 的委托?
  • 是的,当我覆盖委托设置器时,我在手动设置委托后立即调用了 VC 中的委托函数并且它起作用了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2010-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多