【问题标题】:How should I set a default value for a delegate?我应该如何为委托设置默认值?
【发布时间】:2014-05-14 16:04:50
【问题描述】:

我有一个符合协议的具有delegate 属性的类:

MyClass.h

@interface MyClass : NSObject

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

@end

我想为delegate 属性设置一个默认值,就像UITableViewController 所做的那样。

考虑以下几点:

MyClass.m

@interface MyClass ()

@property (nonatomic, strong) id<MyProtocol> defaultDelegate;

@end


@implementation MyClass

- (instancetype)init
{
    self = [super init];

    if (self) {
        _defaultDelegate = // something conforming to MyProtocol
        _delegate = _defaultDelegate;
    }

    return self;
}

@end

这种方法有什么问题吗,或者可以以任何方式改进吗?


更新 #1

接下来呢?

该属性不称为delegate,而是类似于colorPalettefontFamilies,需要一个默认值。

协议中的所有内容都是@required

在运行时,属性的值可以设置为其他值(符合协议的另一个类的实例)。


更新 #2

我正在尝试封装(默认)行为。

考虑到有 3 个类符合协议 - 最初我可能想使用第一个类中的所有值。明天我可能会选择第二个更好的默认值。此外,用户可以在运行时设置一个偏好,它可以使用 3 个中的任何一个。

【问题讨论】:

  • nil 因为向nil 发送消息是nop
  • 另外,约定是委托的默认值应该是零。因此,无论您在哪里调用委托上的方法,都要确保它的行为正常。
  • 如果设置委托值不是可选的,只需断言协议值为 nil。
  • 委托通常是弱(分配)引用和“不”强(保留)。它的默认值为 nil。您可以在没有设置委托的地方实现逻辑。

标签: objective-c automatic-ref-counting delegation


【解决方案1】:

默认值应为 nil。没有理由给它一个价值。当所有其他类都使用它时,预期的行为是需要委托的完整实现。当您开始添加默认值时,您就彻底失败了。

【讨论】:

    【解决方案2】:

    默认情况下,您的委托应为 nil。但是,要实现 UITableView 之类的默认值,您的类应该检查委托是否使用respondsToSelector: 响应每个可选委托方法(如果委托为 nil,它将响应 false)。如果委托没有响应,则使用默认值。您不需要设置“默认委托”来执行此操作。

    您的代码将如下所示:

    NSString *stringValue = nil;
    if ([self.delegate respondsToSelector:@selector(getStringValue)]) {
         stringValue = [self.delegate getStringValue];
    }
    else {
        stringValue = @"Default value";
    }
    

    【讨论】:

      【解决方案3】:

      您可能正在寻找这种实现方式:

      if (delegate == nil) {
          // default behavior
      } else {
          [delegate methodToCallWithParameters:...];
      }
      

      如果您的财产必须实施协议,这是一个类似的问题。

      【讨论】:

        【解决方案4】:

        根据响应的组合,听起来我应该这样做:

        @interface MyClass ()
        
        @property (nonatomic, strong) id<MyProtocol> currentColorPalette;
        @property (nonatomic, strong) id<MyProtocol> defaultColorPalette;
        
        @end
        
        
        @implementation MyClass
        
        - (instancetype)init
        {
            self = [super init];
        
            if (self) {
                _defaultColorPalette = [[SomeClassConformingToProtocol alloc] init];
            }
        
            return self;
        }
        
        - (void)setColorPalette:(id<MyProtocol>)colorPalette
        {
            _colorPalette = colorPalette;
            _currentColorPalette = _colorPalette;
        }
        
        - (id<MyProtocol>)currentColorPalette
        {
            id<MyProtocol> colorPalette = nil;
        
            if (self.currentColorPalette == nil) {
                colorPalette = self.defaultColorPalette;
            }
            else {
                colorPalette = self.currentColorPalette;
            }
        
            return colorPalette;
        }
        
        
        #pragma mark - MyProtocol
        
        - (void)doSomethingWithCurrentColorPalette
        {
            [self.currentColorPalette someDelegateMethod];
        }
        
        @end
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-04-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多