【问题标题】:Where to set delegate = self? Or should I just use a different design pattern?在哪里设置委托=自我?还是我应该只使用不同的设计模式?
【发布时间】:2015-02-16 15:27:05
【问题描述】:

编辑:为清楚起见进行了编辑

免责声明:我是新手,很糟糕。但是我已经非常努力并阅读了很多东西来弄清楚这一点,但我还没有......

我认为我的整个委托模式都可以工作,但我不知道如何在 MatchLetter 类中将 ViewController 的委托属性设置为 self。原因是我不知道如何在那里调用代码。它不是视图控制器,因此 viewDidLoad 或 prepareForSegue 不起作用。

这就是我所拥有的:

ViewController.h

#import <UIKit/UIKit.h>

@class ViewController;
@protocol letterMatchProtocol <NSObject>
- (BOOL) isLetterMatch:(char) firstLetter;
@end

@interface ViewController : UIViewController
@property (nonatomic, weak) id <letterMatchProtocol> delegate;
@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

char c = 'a';

// This is the method I want to delegate to MatchLetter, to have a BOOL returned
BOOL returnValue = [self.delegate isLetterMatch:c];
}

@end

MatchLetter.h

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

@interface Delegate : NSObject <letterMatchProtocol>
@end

MatchLetter.m

#import "MatchLetter.h"

@implementation Delegate

// this is the code I think I need to run here, to set the delegate property...

// ViewController *viewController = [ViewController new];
// viewController.delegate = self;

// ... so that isLetterMatch can be run here from ViewController.m
// But I don't know where to put this code, or how to get it to run before the ViewController
// especially since there are no segues or views to load.

- (BOOL) isLetterMatch:(char)firstLetter {

if (firstLetter == 'a') {
    return YES;
}
else {
        return NO;
    }
}

@end

有人可以告诉我最好的方法吗?感谢阅读

【问题讨论】:

  • 实际创建ViewController 实例的代码在哪里?通常你会在那个时候设置它的delegate
  • 仅供参考 - 将您的班级命名为 Delegate 是个坏主意。您可能会有其他“代表”课程。给它一个更具描述性的名称。
  • 为什么你的视图控制器不是代理?正确的做法通常是让视图控制器成为委托。
  • “我想我明白你必须在实际的委托类中将委托设置为自我,而不是类的实例。” ???你认为有什么不同? (并且您没有在委托类中设置delegate,而是在委托所服务的类中设置它。)
  • rmaddy,感谢您的建议。我在 MatchLetter.m 中添加了创建 ViewController 实例的代码,注释掉了。我不知道调用哪个方法,甚至不知道如何进入 MatchLetter.m。这是我真正的问题

标签: ios objective-c delegates delegation


【解决方案1】:

您问“在哪里设置 delegate = self?还是我应该使用不同的设计模式?”。

答案:不要。一个对象永远不应该是它自己的委托。

你的代码很乱。

不要将类命名为“委托”。委托是一种设计模式。委托的全部意义在于,任何符合特定协议(“说语言”)的对象都可以作为委托。您不需要知道哪个类的对象充当代理,只需知道它使用您需要的语言即可。

打个比方:当您打电话给接线员时,您并不关心接线员是谁在工作。你不关心他/她的性别、宗教、种族背景、他们的身高等。你只关心他们说你的语言。

同样,当您设置委托时,将什么类型的对象设置为委托并不重要。重要的是作为委托的对象符合该委托的协议。

只要该对象符合 UITableViewDelegate 协议,表格视图就可以将任何对象用作它的委托。您通常让您的视图控制器成为表视图的代表,但您不必这样做。您可以创建一个自定义类来管理您的表视图,并让它成为委托。没有“TableViewDelegate”对象类。取而代之的是UITableViewDelegate 协议,任何符合该协议的对象都可以充当表格视图的委托。

编辑:您的问题令人困惑。我认为您的建议是您的 Delegate 类将创建一个视图控制器并使其自身成为视图控制器的委托。

如果这就是你所说的,那你的想法是倒退的。视图控制器使用 Delegate 类作为帮助类。视图控制器类的任何给定实例都可以创建 Delegate 类的实例,并在需要时将其设置为委托。您可能同时拥有 3 个 ViewController 实例,每个实例都有自己的 Delegate 类实例。

因此,如果需要,ViewController 对象应该创建和设置 Delegate 实例:

- (void) viewDidLoad;
{
  self.delegate = [[Delegate alloc] init];
  //other setup here
}

【讨论】:

  • 我只是将类 Delegate 命名为描述。我没想到会引起这么大的混乱。这是我试图在(现已重命名的)MatchLetter 类中设置为 self 的 ViewController 的委托属性。我知道除了@property 创建的对象之外,委托不是对象。为了清楚起见,我已经清理了我的问题。我希望你能花一点时间来理解我的意思
  • 事实上,一个对象永远不应该是它自己的委托。这就像试图对自己进行心脏直视手术。它往往会导致问题。
  • 你是对的。不幸的是,你说的对我没有帮助,因为这不是我想要做的
  • 我确定你知道你在说什么,但我不明白,而且它似乎与这个 SO 答案(简短的答案)相矛盾:stackoverflow.com/questions/626898/… 所以我现在继续。感谢您的努力
  • 你说“......这似乎与这个 SO 答案相矛盾......” 不是真的,不。在该问题的公认答案中,第三个对象为 NSWindow 创建一个委托对象并分配它。请注意,委托对象不会创建它作为委托对象的对象。您是否有一个特定的目标,或者您只是在进行思考练习以尝试了解不同的 Cocoa 设计模式?
猜你喜欢
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多