【问题标题】:Is it bad design to set self.delegate = self设置 self.delegate = self 是不好的设计
【发布时间】:2017-03-09 09:24:39
【问题描述】:

我有一个 UIViewController 子类(比如 MyViewController)。

MyViewController.h

@protocol TargetChangedDelegate
    -(void) targetChanged; 
@end

@interface MyViewController

@property (weak) id<TargetChangedDelegate> targetChangedDelegate;

-(void) doSomethingOnYourOwn;

@end

MyViewController.m

@implementation MyViewController <TargetChangedDelegate>

-(void) doSomethingOnYourOwn
{
  // DO some stuff here

  // IS THIS BAD ??
  self.targetChangedDelegate = self;
}

-(IBAction) targetSelectionChanged 
{
  [self.targetChangedDelegate targetChanged];
}

-(void) targetChanged
{
   // Do some stuff here
}

@end

根据某些条件,实例化 MyViewController 实例的类可能会决定是否将自己设置为委托。

Foo.m

@property(strong) MyViewController *myVC;

-(void) configureViews
{
  self.myVC = [[MyViewController alloc] init];
  [self.view addSubview:self.myVC];

  if (someCondition) 
  {
    self.myVC.targetChangedDelegate = self;
  }
  else
  {
    [self.myVC doSomethingOnYourOwn]
    //MyViewController sets itself as the targetChangedDelegate
  } 

}

参考上面的sn-p代码,我有如下问题: 是否违反 MVC/委托设计模式(或只是一个糟糕的设计)说:

self.delegate = self;

【问题讨论】:

  • 不就是某种actor模型表示吗?
  • 还不错,是错的。当您可以轻松调用没有委托的方法时,为什么要将委托设置为self,作为同一类中委托的定义。当您处理其他一些课程时这是正确的,但在同一个课程中毫无意义。
  • 不确定你想通过这样做来完成什么,可以很容易地用[myVC doSth]调用函数
  • @iphonic 我同意这不是常态,但有原因。特别是在使用子类化时。是好的设计吗? ..也许不是,也许是,但它是务实的。 - 无论我投票结束它,因为它只会产生固执己见的答案

标签: ios objective-c delegates protocols


【解决方案1】:

将代理设置为self 绝对没有问题。事实上,如果委托不是由其他人设置的,这是提供默认委托功能的好方法。

显然,delegate 属性必须声明为weak,否则你会得到一个引用循环。

为了扩展一点,在阅读了上面错误的答案和错误的 cmets 之后,如果您允许一个对象成为它自己的委托,那么您的代码会更简洁,因为您不必用

来绝对包围每个单独的委托调用
if ([self delegate] != nil)
{
    [[self delegate] someMethod];
}
else
{
    [self someMethod];
}

【讨论】:

  • 我跟随你的想法......对我来说,主要是命名“代表”是问题......我通常有像handleSomething或didCompleteX这样的“中间”方法来做到这一点。
  • @iphonic 让一个类符合它自己的委托协议并不违背协议的目的。
【解决方案2】:

分配 self.delegate = self 的方法不正确。 对于您的功能,您可以这样做:

-(void) doSomethingOnYourOwn
{
  // DO some stuff here


  self.targetChangedDelegate = nil;
}

当使用委托时:

if(self.targetChangedDelegate != nil && [self.targetChangedDelegate respondsToSelector:@selector(targetChanged)]
{
   [self.targetChangedDelegate targetChanged];
}
else
{
     [self targetChanged];
}

【讨论】:

    【解决方案3】:

    self.delegate = self; 设置为另一个对象是不好的设计。通过协议委托是子类化的替代设计,您可以在此处阅读有关委托的更多信息:

    https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html

    这里有更多关于协议的内容: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Protocol.html

    【讨论】:

      猜你喜欢
      • 2015-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-21
      • 2018-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多