【问题标题】:iOS - Set Model class to be delegate of another Model classiOS - 将模型类设置为另一个模型类的委托
【发布时间】:2012-12-21 12:13:30
【问题描述】:

我有一个实现协议的 CLLocationManager 单例,所以我可以告诉另一个模型类 (ServerConnection) 已找到用户的更新位置。

在我的AppDelegate方法中,didFinishLaunching,我写

ServerConnection* serverConnection = [[ServerConnection alloc] init];
[LocationManager sharedLocationSingleton].delegate = serverConnection;
[[LocationManager sharedLocationSingleton] getUsersLocation];

这不起作用,我的 ServerConnection 类中的委托方法没有被调用。但是,如果我尝试让我的 AppDelegate 类成为侦听器,如下行所示,它可以正常工作。

// self refers to AppDelegate
[LocationManager sharedLocationSingleton].delegate = self;

在这里,我的 AppDelegate 实现了所需的委托方法,并且当用户的位置更新时调用该方法。

为什么我上面的方法失败了,我尝试将委托设置为 serverConnection?

在线教程通常指向使用 UIViewController 或 AppDelegate 作为“监听器”,但在我的例子中,我想要一个单独的模型类作为监听器。我怎么做?

下面是我的带有协议的 LocationManager 单例类

@class LocationManager;

@protocol LocationManagerDelegate <NSObject>
@required
-(void)LocationManagerUpdated:(LocationManager*) locationManager
                  withValue:(CLLocation*) location;
@end

@interface LocationManager : NSObject <CLLocationManagerDelegate>

@property (strong, nonatomic) CLLocationManager* locationManager;
@property (strong, nonatomic) CLLocation* location;
@property (weak, nonatomic) id <LocationManagerDelegate> delegate;

+(LocationManager*)sharedLocationSingleton;
-(void) getUsersLocation;

@end

我的服务器连接头文件是。

#import <Foundation/Foundation.h>
#import "LocationManager.h"

@interface ServerConnection : NSObject <LocationManagerDelegate>
@end

这在 AppDelegate 设置为侦听器时有效,但不是我的模型对象 ServerConnection。我该如何解决这个问题?

谢谢!

【问题讨论】:

  • ServerConnection接口定义是什么?

标签: iphone ios xcode model delegates


【解决方案1】:

做你想做的事情应该没有问题(即,让一个非控制器类实例充当委托)。

这在 AppDelegate 设置为侦听器时有效,但不是我的模型对象 ServerConnection。

您的ServerConnection 类是否实现了LocationManagerDelegate 协议? (我的意思是实现而不是仅仅在其接口中声明它)。

检查负责调用委托方法 (LocationManagerUpdated:) 的 LocationManager 方法,并在其中添加一个 NSLog 跟踪,以在您尝试向其发送消息时检查委托对象是否已正确设置。

编辑:

ServerConnection* serverConnection = [[ServerConnection alloc] init];
[LocationManager sharedLocationSingleton].delegate = serverConnection;
[[LocationManager sharedLocationSingleton] getUsersLocation];

在您发表评论后,很明显问题源于在堆栈变量中而不是在属性中实例化 serverConnection

您将delegate 属性设置为强属性的方法不正确,因为it leads to retain cycles。您需要做的是在执行我上面粘贴的代码的类中定义一个strongserverConnection 属性(应用程序委托?)。

如果您不介意我的鲁莽,如果您将委托定义为强属性,那么您所做的就是通过添加隐藏第一个错误的第二个错误来修复错误。

【讨论】:

  • 谢谢!通过将委托的属性声明从弱更改为强来解决此问题
  • 将委托设置为强属性会导致灾难,因为它会导致循环依赖:stackoverflow.com/questions/8449040/…
【解决方案2】:

看起来serverConnection 没有保留在任何地方,因为delegate 属性被指定为weak,所以它被释放并设置为nil。

检查 getUsersLocation 方法并查看在您尝试调用 LocationManagerUpdated:withValue: 时委托是否为零

【讨论】:

  • 谢谢!我通过使委托属性强而不是弱来修复它
  • 您不应该使委托属性变得强大。我建议考虑其他解决方案。问题是,你为什么不在任何地方保留serverConnection。也许您不需要这个delegate 属性,只需将serverConnection 作为您的LocationManager 的私有属性
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-07
  • 1970-01-01
  • 1970-01-01
  • 2012-02-07
  • 2010-10-18
  • 1970-01-01
相关资源
最近更新 更多