views:

110

answers:

4

This is really a few questions in one, I'm wondering what the performance cost is for these things, as I haven't really been following a best practice of any sort for these. The answers may also be useful to other readers, if somebody knows these.

(1) If I need the core data managed object context, is it bad to use

#import "myAppDelegate.h"
//farther down in the code:
NSManagedObjectContext *context = [(myAppDelegate.h*)[[UIApplication sharedApplication] delegate] managedObjectContext];

as opposed to leaving the warning you get if you don't cast the delegate?

(2) What is the cheapest way to hard-code a string? I have been using

return @"myString";

on occasion in some functions where I need to pass it to a variety of places, is it better to do it this way:

static NSString *str = @"myString";
return str;

(3) How costly is it to subclass an object i wrote vs. making a new one, in general?

(4) When I am using core data and navigating through a hierarchy of some sort, is it necessary to turn things back into faults somehow after I read some info from them? or is this done automatically?

Thanks for any help.

A: 

I'll answer one of these...

2) The two are equivalent. A hard-coded string is a read only object that is only instantiated once, and you are only storing and returning a pointer to it. The only way you can "fuck this up" is by doing something like NSString *string = [NSString stringWithString: @"a constant string"] which would indeed create a copy.

Question number three doesn't make sense to me. Subclassing is a different concept than instantiating, and carries no cost in itself...

calmh
Sorry 3 wasn't too clear, what I meant was to subclass a class I wrote already, as opposed to writing a new different class.
Alex Gosselin
+3  A: 

1) Casting your delegate doesn't change anything at runtime, all it does is prevent the compiler from producing a warning. The word "costly" does not apply.

2) @"Foo" represents a pointer to an NSString object whose contents are 'Foo'. If there is such a string already in memory, it will be used; otherwise, a new one is created.

NSString *fooStr = @"Foo"; will place a pointer to the 'Foo' string into the variable fooStr

The static keyword changes the scope of the variable but otherwise has no performance effect (see this question on static variables for more info).

3) "Making a new object" would mean subclassing NSObject. You can't get away from subclassing, and the only cost difference is the memory footprint of the class you're inheriting from.

4) You should not worry about faults. Let core data take care of it all for you. It owns the life cycle of managed objects and handles all the memory management and faulting.

Victorb
1) does this mean that using #import has no effect on performance or memory footprint?2) That makes sense3) good point, never thought about it that way4) Awesome.Thanks for the good answers.
Alex Gosselin
`#import "Foo.h"` just causes the preprocessor to replace that line with the entire contents of the file `Foo.h` (with a check to ensure it doesn't get included multiple times). Once again, that only has relevance at the compiler level and has nothing to do with runtime performance.
Victorb
+1  A: 

(1) You only have the very minor overhead of function call. The cost would be to small too measure.

(2) Literal strings are created as atoms. There is no overhead. In both cases you return the same pointer to the same address. String operations are very efficient. You only need to pay attention to them if your doing thousands of them sequentially.

(3) Subclassing is a function of the compiler, it has no performance implication when running the app.

(4) Core-Data will handle most of your faulting.

In general, these types of issues are ones you should ignore until the app is complete and you find a performance bottleneck. Premature optimization is the root of all evil.

TechZen
Good explaination.
Macmade
Root of all evil, haha I already stripped away all my code and re-wrote it because it had turned to very optimized but unmaintainable spaghetti once, round 2 is going much better though.
Alex Gosselin
A: 

Regarding 1, although it'll work, it's not best practice to access the managed object context like that. From Apple's documentation:

By convention, you can often get a context from a view controller. It’s up to you, though, to follow this pattern. When you implement a view controller that integrates with Core Data, you can add an NSManagedObjectContext property.

A view controller typically shouldn’t retrieve the context from a global object such as the application delegate. This tends to make the application architecture rigid. Neither should a view controller typically create a context for its own use. This may mean that operations performed using the controller’s context aren’t registered with other contexts, so different view controllers will have different perspectives on the data.

When you create a view controller, you pass it a context. You pass an existing context, or (in a situation where you want the new controller to manage a discrete set of edits) a new context that you create for it. It’s typically the responsibility of the application delegate to create a context to pass to the first view controller that’s displayed.

Thus, when you set up a view controller, you're supposed to pass in the Managed Object Context then, with each view controller passing it along to each child view controller as they are created.

For example:

DesignController *designController = [[DesignController alloc] initWithNibName:nil bundle:nil];
designController.delegate = self;

// Pass in your MoC here, along with the rest of the setup
designController.managedObjectContext = self.managedObjectContext;

[self.navigationController pushViewController:designController animated:YES];
Amorya