5

I'm new to Cocoa and looking for a little advice for an application from experienced Cocoa-ers. 

I'm building a basic OmniGraffle-style app where objects are drawn/dragged onto a canvas. After the objects are on the canvas, they can be selected to modify their properties (fill color, stroke color/width, etc.), be resized, moved around to a new position, etc.

To get warmed up, I've written a basic drawing app that creates objects (circles, rectangles, etc.) as drawn by the mouse on a custom NSView, adds the objects to an NSArray collection, and renders the contents of the collection into the view. I could continue in this vein, but I'm going to have to add support for detecting object selection, resolving z-indexing, focus highlighting, drag handles, etc. with all the associated rendering. Also, rendering every object on each cycle seems terribly wasteful.

It seems like a better approach would be to drop lightweight view objects onto a canvas that were able to detect mouse events on themselves, draw themselves and their focus rings, and so forth. However, while NSView seems like an object with these properties, I see a lot of chatter on the web about it being a heavyweight component with a lot of baggage. I've stumbled across NSCells and have read up on them, but I'm not sure if they are the right alternative.

Any suggestions? If you can nudge me in the right direction I'd greatly appreciate it.

Rob Keniger
  • 45,830
  • 6
  • 101
  • 134
mrflibble
  • 101
  • 1
  • 2
  • I'd definitely advise against using `NSCell`. Even `NSTableView` has moved away from it in its latest iteration. `NSCell` is not fun to work with. – Rob Keniger Aug 27 '11 at 02:51
  • 1
    I'd also *highly* recommend you look at the Sketch example (I think the current one is called "Sketch+Accessibility" if you search the docs) if you haven't already. There are a lot of good ideas in there. – Rob Keniger Aug 27 '11 at 02:56

1 Answers1

3

First rule of optimization: Don't do it first.

A custom NSView per shape sounds about right to me. Whether you'll want different subclasses for different shapes will be up to you; I'd start out with a single generic shape-view class and shapes able to describe themselves as Bézier paths, but don't be too strict about holding to that—change it if it'd make it easier. Just implement it however it makes sense to you.

Then, once you've got it working, profile it. Make as many shapes as you can. Then make more. High-poly-count shapes. Intersections. Fills, strokes, shadows, and gradients. You probably should create a separate document for each stressor. Notice just at the user level what's slow. Then, run your app under Instruments and look into why it's slow.

Maybe views will turn out to be the wrong solution. Don't forget to look into CALayers. But don't rule anything out as slow until you've tried it and measured it.

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
  • Well, all depends on the typical use case - if the app is expected to usually handle thousands of objects I'd rather shy away from using thousands of NSView instances and choose a different design upfront. – Jay Mar 27 '12 at 06:42