This question is specific to iOS development.
Imagine you use UITableView and inside the UITableViewCells you show information regarding one or more of your application business objects through a bit more complex class that we’ll call ComplexBOView.
Now you want to trigger a specific action when the user taps this view contained in your UITableCellView (the event can be triggered through a UITapGestureRecognizer)
Most of the time what is considered “best practice” is to use the tag property of the UIView to actually go back to your model and retrieve the correct business object.
This often is suitable but in some cases it can come very handy to hold a pointer to the business object used to built your ComplexBOView.
@interface ComplexBOView : UIView
{
UILabel* lblSummary;
// ....
UITapGestureRecognizer* tapGesture;
NSObject* businessObject_;
}
@property (nonatomic, readonly) UITapGestureRecognizer* tapGesture;
@property (nonatomic, assign) NSObject* businessObject;
The idea behind this, is to actually directly go back to the businessObject when the user tapped the view.
Two questions here
- Is it really bad to have NSObject* information inside the UIView ?
- Should this information be retained meaning the relationship between the view and the model becomes here much stronger (ownership of the view towards the object) ?
Thanks for your advice.
The general advice is
and it’s a good advice. It can save you a lot of trouble in the long run. But what does own mean? If you look at a
UIButtonor aUILabel, the button has atitlethe label atextproperty. So they are holding some data, they have to – the alternative would have to have a delegate that is asked for the text every time they get drawn.So what does that mean in your case? Well that depends. If your
ComplexBOViewis just generic view that is specifically designed to display your specific business object, it wouldn’t be the worst to hold that object in a property of it (just my opinion).Of course you loose the possibility to easily reuse that view with a different model, but maybe that isn’t an option anyway, because it’s so specific. Of course you could move all that code from the
ComplexBOViewto the controller. But as you said then you also have to maintain a connection between each model object and the appropriate view. (Btw. I wouldn’t use thetagto do that, it’s better to just use an `NSDictionary instead)On the other hand Trausi and Michael do have valid points. If you break that “rule” this one time, you might get loose and break it on every other occasion and before you know it, you end up with lots of custom views each holding a reference to some part of your model. In the long run you might make changes to your model (maybe in ways you never expected in the first place – and trust me, that is going to happen more often than not) and then you have to go to every single subclass and adjust them. Of course if that model-specific code lives in your controller you also have to modify all of that, but at least it’s all in one place.
So to sum up, those best practices, advice and design patterns are there for a good reason. They proved themselves useful in countless cases. So in general you do good by just following them. There are however cases where it might be worth violating them, but you have to have some very good reasons and you should be aware of the consequences.
Ultimately, it’s your code, your design, your decision. Maybe you guess wrong, but some lessons have to be learned the hard way. Next time you know what to do and, more important, why. Making your own experiences is always valuable.