Objective-c: Objects by value / Structs with methods / How can I get something like that?
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 oriente开发者_Python百科d.
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.
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.
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.
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.
精彩评论