0

I'm creating a custom subclass of UIView. I'm currently doing initialization based on Objective C - Custom view and implementing init method?, so that there's some initialization that gets done whether loading from code or from a xib.

The problem I have now is that I am adding a property that is 'required' (let's call it reqProp for discussion's sake) - the view can't render without this property being set, and it must be set before any other functionality specific to my view subclass can be used.

Because of this, I figured the natural place to enforce this requirement would be to provide a new init function, so I don't have to worry about it not being set throughout the rest of my code - for example

initWithFrame:(CGRect)frame forReqProp:(NSString *)reqProp;

However, I'm not sure how to enforce the same requirement when initializing through initWithCoder.

The closest I can think of is to require specifying this property in User Defined Runtime Attributes (right under where the Custom Class name would need to be defined in interface builder), but in that case, it's not clear when/if I should "blow up" because of the property not being specified.

The only other option I can think of is just have very explicit documentation that this required property must be the first thing set before using the view.

Community
  • 1
  • 1
Krease
  • 15,805
  • 8
  • 54
  • 86
  • Only sensible default comes to mind. – Eimantas Jul 30 '12 at 22:39
  • I can't default to anything for this particular property - it must be specified by the developer using this view. To put it another way - any default I pick would be wrong, and the developer using the view would need to change it before they use the view. – Krease Jul 30 '12 at 23:48

2 Answers2

0

I'm not at my XCode capable computer right now, so I can't test this, but how about presenting a sheet from the initWithCoder method, that would require the user to input the value for reqProp before the method completes.

rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • Do you mean prompting for user input during initWithCoder? That seems very wrong... – Krease Aug 01 '12 at 16:49
  • Yeah, after thinking about it more, I think you're right, that probably is a bad idea. Could you do it in viewWillAppear, or is that too late in the process? It seems like that's the place to do this rather than in an init method. – rdelmar Aug 01 '12 at 20:39
0

If the problem can be solved by requiring that it is the first property set before using the view, then it's not really required for initialization. The recommendation here would be good documentation.

However, the underlying problem might be better solved by some refactoring, so it's not required to be the first property set. In this case, a very basic refactoring could involve storing a dictionary of the other properties, and only "really" setting them (and having an effect on the rendering) after the required property is set.

For example:

- (void) setOptionalProperty1:(id)prop
{
    [propMap setObject:prop forKey:@"property1"];
    if (self.requiredProperty) {
        _optionalProperty1 = prop;
    }
}

- (void) setOptionalProperty2:(id)prop
{
    [propMap setObject:prop forKey:@"property2"];
    if (self.requiredProperty) {
        _optionalProperty2 = prop;
    }
}

- (void) setRequiredProperty:(id)requiredProp
{
    _requiredProperty = requiredProp;
    // now iterate over propMap and set those properties properly
}

It's not necessarily the best refactoring, but a generic simple example that should get the job done and keep the underlying restriction (required property must be set first) intact without forcing that requirement on developers using the class.

Krease
  • 15,805
  • 8
  • 54
  • 86