I am not sure if many of you are familiar with the box2d physics engine, but I am using it within cocos2d and objective c.
This more or less could be a general objective-c question though, I am performing this:
NSMutableArray *allShapes = [[NSMutableArray array] retain];
b2PolygonShape shape;
..
..
[allShapes addObject:shape];
and receiving this error on the addObject definition on build:
cannot convert 'b2PolygonShape' to 'objc_object*' in argument passing
So more or less I guess I want to know how to add a b2PolygonShape to a mutable array. b2PolygonShape appears to just be a class, not a struct or anything like that. The closest thing I could find on google to which I think could do this is described as 'encapsulating the b2PolygonShape as an NSObject and then add that to the array', but not sure the best way to do this, however I would have thought this object should add using addObject, as some of my other instantiated class objects add to arrays fine.
Is this all because b2PolygonShape does not inherit NSObject at it's root?
Thanks
b2PolygonShape is a C++ class, not an ObjC class. You can only put ObjC instances into "NS-containers".
Since you need C++ anyway, it's better to use a std::vector<b2PolygonShape>.
NS-container classes can (as KennyTM pointed out) only store NSObjects. This can be a bit of a pain sometimes. But there are plenty of alternatives to NS-containers.
You can write Objective-C wrapper classes (or use NSValue), and store these in an NSArray.
You could use a plain old C array (though, that may not serve your needs, if the array size is undefined and shrinks and grows)
You could use a hash table to store your references.
A linked list of structs can also come in handy, and is fairly easy to create and maintain.
Should you decide to stick to std::vector, which is as good a solution as any, you can read more about that at: http://www.cplusplus.com/reference/stl/vector/
Related
id<UIView> views = #[one, two, three];
NSInteger object = [views lastObject]; // Compiler will warn me that `views` stores only UIViews
How far would I have to go implement this? Does anybody have some experience with extending clang to support similar features?
Similar: nsmutablearray-force-the-array-to-hold-specific-object-type-only
I have thought about this also, though in the end I ask would it actually make me more productive. Objective-C seems to me to be a very pragmatic language, the features it has are real world useful, things like block are super useful, but features like namespaces and typed arrays in my experience not so much. I add a lot of NSAssert to my code to check stuff like that. Usually my mutable collections are contained within other classes and so I have a lot of control over what can be added to them, but maybe thats a pattern I adopt because I don't have typed collections?
Well, technically you already can...
UIView *views[] = {one, two, three};
NSInteger object = views[2];
Or, more usefully, you could use Objective-C++.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
what is the point of pointers in objective language
I am confused as to when and why pointers are used in Obj-C code. I am new to Obj-C and have a good grounding in C++ from an intro course at my university.
NSDate *now = [NSDate date];
Why is a pointer used here (and what exactly is its purpose?), and not here...
NSUInteger arrayLength = [<some array> count];
I am much more comfortable with the second example, but the first is still puzzles me.
It's the wording of the typedefs of Apple which are confusing.
NSUInteger
is just a fancy typedef for unsigned int; therefore it's a scalar type and not an object; you don't need a pointer to it in general for such a simple use case.
However,
NSDate
is a Foundation class; it means that its instances are proper Objective-C objects. As you probably know, Objective-C is a fully dynamic language: no static instances of classes are permitted, so every object is essentially a pointer (well, rather the allocated memory behind the pointer). So when you work with Objective-C objects, you always need a pointer to them.
Well, there are a few fundamental differences between Objective-C and C++. In Objective-C, there is actually a "generic object" (type "id"), and you can pass objects around without worrying about classes.
One of the implementation details that makes this possible is that Objective-C doesn't have "static" objects; all objects are created through the equivalent of "new" and are accessed through a pointer (string literals might be different, but they are still of type "NSString*"). It's just the way it is in Objective-C; you simply cannot have an "NSString MyString".
Because of this, the whole "objects are just objects and the compiler doesn't actually what you're dealing with" is possible because all objects are just simple pointers -- they are all the same size. The compiler can pass them around without knowing what they are, you can store them in containers without the containers knowing what they are etc.
Objective-C and C++ may both be "object-oriented" extensions of C, but they are quite different nonetheless.
EDIT: you can write stuff like "NSString* MyString" so the compiler knows what kind of object it is dealing with, but that's just convenience: you can still put other objects into that pointer (and, in fact, since the "new" equivalent usually returns id, one of the more common mistakes that I make is to "new" a different class from what the pointer says)
On the positive side, the compiler will warn you if you assign e.g. an NSWindow* to MyString, and it will also warn you if you call "open" on MyString. However, this is just an added benefit from the compiler; you could just as well declare everything as "id", or cast away the warnings.
I'm developing an iPhone 3.1.3 application.
I have a class, called Object2D, with fields and methods; which represent a shape. Object2D has a field that represents its size, and another field that represent its type.
Now, I need another class called Pattern, which is a set of shapes. In Pattern I'm going to have an array of shapes. From these shapes I only need their size, their type and their location inside pattern, I don't need any method.
I'm wondering it is better to have a new struct that represent a shape instead of using Object2D class.
I ask this because I think on memory performance. I'm not sure, but struct are smaller than classes and maybe it's better to use them instead of classes.
What do you think?
If you're looking at memory use, the difference is truly negligible in almost every situation. Objects are one pointer bigger than an equivalent struct.
The greater difference is in how you can use them. Objects can have methods and hierarchies and interact with the rest of Cocoa. With structs, you need to make custom functions for each struct type or hack together a pseudo-object system. On top of that, arbitrary structs don't interact well with the rest of Cocoa (Touch). For example:
If you store objects in them, you have to be very careful to do your own memory management correctly
You can't store them in NSArrays without creating an object wrapper (since NSArray is an array of objects)
You can't hook structs up in Interface Builder — it doesn't know anything about them
You can't do KVO or KVC with structs
In general, if you're working with a Cocoa-like framework, objects are a good default choice. Use structs once you've decided you really need them.
Objective-C classes are in fact structs, and, provided the instance variables are laid out in the same order as the structure members are, the only difference in size is the 4 or 8 bytes of NSObject's isa variable.
NOTE: the answer above assumes the legacy Objective-C runtime, without the use of #property and #synthesize directives, which could potentially affect their size.
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.
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.
I want to ask a question about the objective C. When I study the library from the apple developer website. I always see that there are some subclass called "mutable". For example, the NSArray and NSMutableArray. What does it mean about this word. Are there some special meaning? Can anyone tell me? Thank you.
It means you can change its values. If you look at the NSMutableArray docs, you'll see it defines extra methods like -addObject:. NSArray by itself doesn't have these (and can thus be more efficient / take less memory in implementation).
Also note, if you call [myMutableArray copy] you'll get a non-mutable copy of it (which you must later release0. And similarly there's -mutableCopy.
Mutable means you can change it. Look at the difference between addObject in NSMutableArray and arrayByAddingObject in NSArray.
From the Objective-C Beginner's Guide it states the answer to your specific question:
There are two kinds of arrays (and of
usually most data oriented Foundation
classes) NSArray and NSMutableArray.
As the name suggests, Mutable is
changable, NSArray then is not. This
means you can make an NSArray but once
you have you can't change the length.
This tech note also implies you can change the length of a mutable array after the array has been created.
In general mutability stems from these meanings. This will help provide a more broad understanding for when you encounter it elsewhere.