RFInitializing 1.3.0

RFInitializing 1.3.0

BB9z 维护。



  • 作者:
  • BB9z

RFInitializing

Build Status CocoaPods Compatible

通过使用 RFInitializing,对象的初始化变得更容易。

让我们通过一个示例来比较一下。

在根类中

之前之后
@implementation BaseView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self commonSetup];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self commonSetup];
    }
    return self;
}

- (void)commonSetup {
    // do something
}

@end
@implementation BaseView
RFInitializingRootForUIView

- (void)onInit {
    // do the common setup
}

- (void)afterInit {
    // do somthing after the inistance
    // has been initialized
}

@end

在子类中

之前之后
@implementation FooView

- (instancetype)initWithBar:(Bar)bar {
    self = [super initWithFrame:CGRectZero];
    if (self) {
        [self commonSetupForSubclasss];
        _bar = bar;
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self commonSetupForSubclasss];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self commonSetupForSubclasss];
    }
    return self;
}

- (void)commonSetupForSubclasss {
    // do something
}

@end
@implementation FooView

- (instancetype)initWithBar:(Bar)bar {
    self = [super initWithFrame:CGRectZero];
    if (self) {
        _bar = bar;
    }
    return self;
}

- (void)onInit {
    [super onInit];
    // common setup for subclasss
}

@end

目的

一遍又一遍地写 init 方法很无聊,尤其是有太多要覆盖的 init 方法。例如,如果您想子类化 UIView,您可能需要覆盖 init、frameInit 和 initWithCoder 方法。如果您想从该类创建子类,您也必须再次覆盖这些方法,WTF。

是时候结束这些无意义的重复了。通过符合 RFInitializing,您只需要在根类中写一次这些 init 方法,然后子类中只需实现 onInitafterInit,不再要有 init。

注意,如果一个类符合 RFInitializing,则在初始化期间和 init 方法返回之前应该调用 onInit。但 afterInit 应在该方法完成并通常调用 init 方法后调用。例如

- (void)viewDidLoad {
    [super viewDidLoad];

    // RFButton conforms to RFInitializing.
    RFButton *button = [[RFButton alloc] init];
    // `onInit` was called before here.

    // Do some config.
    button.icon = [UIImage imageNamed:@"pic"];

    // Any other code.
    // `afterInit` won't be called in this scope.
}
// `afterInit` will be called after viewDidLoad executed in this example.

使用

您应该在符合此协议的根对象中调用 onInitafterInit。并且 afterInit 必须延迟。以下是一个示例

- (id)init {
    self = [super init];
    if (self) {
        [self onInit];
        // Delay execute afterInit, you can also use GCD.
        [self performSelector:@selector(afterInit) withObject:self afterDelay:0];
    }
    return self;
}

在子类中,您不能在 init 方法中调用这些方法。您可以为您自己的定制实现 onInitafterInit。并且,如果覆盖了 onInitafterInit,在实现中应某个点调用 super。

// If you had to add another init method.
- (instancetype)initWithSomething:(id)some {
    self = [super init];
    if (self) {
        // Don't call onInit or afterInit.
        self.something = some;
    }
    return self;
}

- (void)onInit {
    [super onInit];
    // Something
}

- (void)afterInit {
    [super afterInit];
    // Something
}

更多

你可以在https://github.com/RFUI找到更多示例,例如RFCheckbox。