views:

71

answers:

3

I'm starting to code in objective-c and I've just realized that objects can only be passed by reference. What if I need an object to use static memory by default and to be copied instead of referenced?

For example, I have an object Color with 3 int components r, g and b. I dont want these objects to be in dynamic memory and referenced when passing to functions, I want them immutable and to be copied like an int or a float.

I know I can use a c struct, but I also need the object Color to have methods that gets/sets lightness, hue, saturation, etc. I want my code to be object oriented.

Is there any solution to this?

EDIT: If for example I'm building a 3d game engine, where I'll have classes like Vector2, Vector3, Matrix, Ray, Color, etc: 1) I need them to be mutable. 2) The size of the objects is roughly the same size of a pointer, so why would I be copying pointers when I can copy the object? It would be simpler, more efficient, and I wouldnt need to manage memory, specially on methods that returns colors. And In the case of a game engine, efficiency is critical.

So, if there is no solution to this... Should I use c-structs and use c-function to work on them? Isn't there a better choice?

Thanks.

A: 

One solution that people use sometimes is to use a singleton object (assuming you only need one of the objects for your entire app's lifetime). In that case, you define a class method on the class and have it return an object that it creates once when it is first requested. So you can do something like:

@implementation MyObject

+ (MyObject *)sharedObjectInstance
{

    static MyObject *theObject=nil;

    if (theObject==nil) 
    {
        theObject = [[MyObject alloc] init];
    }

    return theObject;
}

@end

Of course the object itself isn't what's being statically allocated, it's the pointer to the object that's statically allocated, but in any case the object will stick around until the application terminates.

There are times when you want to do this because you really only want one globally shared instance of a particular object. However, if that's not your objective, I'm not sure why you'd want to do what you're describing. You can always use the -copy method to create a copy of an object (assuming the object conforms to the NSCopying protocol) to manipulate without touching the original.

EDIT: Based on your comments above it seems you just want to have immutable objects that you can copy and modify the copies. So using -copy is probably the way to go.

Andrew Madsen
That method needs to return a pointer.
Chuck
So it does! Sorry about the typo. Fixed.
Andrew Madsen
+2  A: 

You can't do this. This isn't how Objective-C works (at least the Apple/GNU version*). It simply isn't designed for that sort of extreme low-level efficiency. Objects are allocated in dynamic memory and their lifetimes are controlled by methods you call on them, and that's just how it works. If you want more low-level efficiency, you can either use plain C structs or C++. But keep in mind that worrying about this is pointless in 99% of circumstances — the epitome of premature optimization. Objective-C programs are generally very competitive with C++ equivalents both in execution speed and memory use despite this minor inefficiency. I wouldn't go for a more difficult solution until profiling had proved it to be necessary.

Also, when you're new to Objective-C, it's easy to psych yourself out over memory management. In a normal Cocoa (Touch) program, you shouldn't need to bother about it too much. Return autoreleased objects from methods, use setters to assign objects you want to keep around.

*Note: There was an old implementation of Objective-C called the Portable Object Compiler that did have this ability, but it's unrelated to and incompatible with the Objective-C used on Macs and iOS devices. Also, the Apple Objective-C runtime includes special support for Blocks to be allocated on the stack, which is why you must copy them (copy reproduces the block in dynamic memory like a normal object) if you want to store them.

Chuck
I don't think it's premature optimization: If I'm building a 3d game engine, where I'll have classes like Vecto2, Vector3, Matrix, Ray, Color, etc. I'm 100% sure that this will be inneficient.
Damian
If you are concerned about the performance, _don't_ use Objective-C classes but use C structs for elements you're going to use _a lot_. Instance variables in Obj-C can only be access through method calls, those take a lot longer than just accessing a variable of a struct.
Georg
@Georg: It's not really true that Objective-C instance variables can only be accessed through method calls. That's just how it's conventionally done.
Chuck
@Damian: As I said, it's always inefficient in some sense — just usually not enough to make any real difference in the behavior of your program. There are a few cases where Objective-C objects just really aren't a good match, and the core data structures of a 3D engine seem like good candidates for this — in that case, as I said, you can either use plain C structs or C++ classes. Those are the options the language gives you. (And I mean, considering people use Python to write games, you have to keep things in perspective.)
Chuck
@Chuck: True,but that creates more problems than it's worth. Forget about dynamic typing for example.
Georg
A: 

What if I need an object to use static memory by default and to be copied instead of referenced?

You don't.

Seriously. You never need an object to use static memory or be allocated on the stack. C++ allows you to do it, but no other object oriented language I know does.

For example, I have an object Color with 3 int components r, g and b. I dont want these objects to be in dynamic memory and referenced when passing to functions, I want them immutable and to be copied like an int or a float.

Why do you not want the objects to be in static memory? What advantage do you think that gives you?

On the other hand it's easy to make Objective-C objects immutable. Just make the instance variables private and don't provide any methods that can change them once the object is initialised. This is exactly how the built in immutable classes work e.g. NSArray, NSString.

JeremyP
Why do you not want the objects to be in static memory? What advantage do you think that gives you? Well, as I commented in the main question: For example if I'm building a 3d game engine where efficiency is critical, cartain classes like Vector2, Vector3, Ray, Color, etc. has to behave like that. It would be simpler, more efficient, and I wouldnt need to manage memory, specially on methods that returns these objects.
Damian
What makes you think an object in static memory will be more efficient than a dynamic one? You'd have to copy the whole object around rather than just passing a pointer.
JeremyP
With more efficient I mean faster. If the size of the object is roughly the same than the size of a pointer, it is faster. Why would I copy and pass a pointer if I can copy and pass the object at the same cost? Then it wouldn't be necessary to dereference it.
Damian
Can you post details of the profiling you have done to prove that you can get a significant speed up? To give you some idea, the overhead of obj_msgsend is about 20 machine instructions. I would think your optimisation is going to be negligible compared with that and if obj_msgsend becomes a performance issue, you'd be better off with C structs (NB cocoa already uses C structs for things like points and rectangles.)
JeremyP