Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Not storing references to delegates #1
Thanks for the great initiative and write up, Jack!
I'm not sure separating delegates out as separate classes is a good way to go since it will undoubtedly require access to several (sub)views and data which are typically accessible from the controller already. I'd normally just use #pragma marks to break them up in ObjC. I'm afraid I'm not proficient enough in Ruby to recommend a better way.
That aside, here's a thing that might be thorny:
Since references to delegates in Cocoa (Touch) classes are often weak references and ditto in RubyMotion, a line like this will often not work:
self.view.delegate = OrganizedViewDelegate.new
Of course! I didn't even think about this when I was coming up with the structure... Thank you so much for pointing that out.
As views pass themselves to their delegates most of the time, I don't see too many situations where using an object that isn't the controller should be a problem (though testing this in the wild might just make that problem emerge). What are some scenarios you're concerned about?
I can think of two options at the moment (I really want to make controllers cleaner and smaller), the first being the way I have been doing it up until now, by using a module and including it in the controller, or doing something like
def init super self.view = ViewWithADelegate.new self.view.delegate = self.view_delegate self end def view_delegate @view_delegate ||= TheDelegate.new end
A barebones example is a view controller containing a table view. Following the guideline, the table view's dataSource and delegate will be a separate (or quite unlikely, 2 separate) class. The view controller will need to pass the model to the dataSource/delegate(s). If you tap on a cell and the controller needs to do something, the controller itself has to be passed to the table view's delegate.
class ViewController def some_setup_within_controller tv = UITableView.alloc.initWithFrame(bounds) tv.delegate = TableViewDelegate.new tv.delegate.controller = self tv.delegate.model = model tv.dataSource = TableViewDataSource.new #might be the same as delegate? tv.dataSource.model = model #tv.dataSource.controller = self #maybe? end end class TableViewDelegate def tableView(tv, didSelectRowAtIndexPath:indexPath) #ask controller to do something with indexPath #does TableViewDelegate know about controller or is it another delegate/"interface"? end end
This gets unwieldy quickly once this particular screen (and hence the controller) becomes more complicated, especially with a custom-built view and subviews.
IMHO, the controller is really a good place to coordinate this most of the time and while it tends to grow into a fatter class, breaking it up into delegates might not be good. Since delegates tend to work with each other or have call common code. What can be separated out from the view controller is the view hierarchy. I wrote about this (but for ObjC) sometime ago. On the other hand, this might just be a consequence of the nature of apps I build. They tend to have custom screens, so maybe I'm in the minority :)
I really like how Rubyists are more aggressive with separating concepts though, so hopefully there is a more elegant way of doing this.