Alternative to Objective-C objects in structs (ARC) - objective-c

I have the following code here that won't run on ARC since it combines Objective-C objects in structs:
struct SingleToManyRelation {
id singleObject;
NSSet* manyObjects;
}
I know this is reminiscent of Core Data, but that's not the point ;) I am just looking for a solution to implement something like that without having to create a "container" class.
Thanks in advance for your advices,
Christian

Give your objects the __unsafe_unretained attribute and ARC will stop complaining (but keep in mind that they aren't retained! So you have to somehow store a strong relationship to them, if you don't want to lose them)

Related

Linked list creation in objective c

Is there a way to create linked list in objective c. I'm a newbie and so far I've researched in apple developer guides, there isn't any function predefined for linked list. Is doubly linked list same as linked list in objective-c?
Please help.
First thing to keep in mind is that Objective-C is C, it's just a lot more, too.
Next thing is that Objects are passed around as (essentially) pointers (which the compiler knows point to objects).
So you can certainly make and manage your own linked list, and you can do it with structs or objects. With objects (perhaps preferred), just create a #property in the class for the "next" object, and use it as you please. Similarly for a doubly-linked list, have a #property for previous.
Perhaps one of the best arguments against caring about liked lists in Objective-C is that usually you have the Cocoa Frameworks at hand, and there is such rich host of features which we used to have to implement ourselves with linked lists. For instance, the conceptually simple NSMutableArray, or NSDictionary are great examples of well-built components which usually spare us the need for linked lists. Going further, Core Data, etc...
A simple abstract linked list class might look like this:
#interface LinkedNode : NSObject
#property (nonatomic, strong) id nextNode;
#end
then you use it as you would expect:
id currentNode = myFirstNode;
do {
[currentNode someMessage];
}
while(currentNode = currentNode.nextNode);
Keep in mind that this is really no "better" than doing it with structs. For the "better" business, move to the Cocoa classes and implement at a "higher level", so-to-speak.
Please check my implementation of some of the common data structures like linked list, stack, binary search tree in objective C.
https://github.com/udaypatial/Data-Structures-in-Objective-C

Circular references in iPhone Cocos2D game programming textbook

an abused topic but I couldn't find an answer to this. I am following the "Learn iPhone and iPad cocos2d Game Development" book and cannot really understand if the approach in the ShootEmUp example (available at 1) is the best one. The author uses a GameScene to which adds as child various objects (e.g. Ship, InputLayer etc..). The controversial aspect is that within those object there are calls to the GameScene via using a static method that returns a static instance of the GameScene class that is instantiated in the init method of GameScene. This to me seems a circular reference and according to many (e.g. see this post) is something to avoid. I am not quiet sure if that's also true in Game Programming as this approach is found in 1 and there might be a reason for this.
Would anyone be able to clarify? I am undecided whether to restructure my code completely or keep the static variable approach.
Thank you very much :)!
Source code
What you see here is a semi-singleton pattern, and it is used extensively throughout Cocos, in fact the Cocos framework itself is built entirely on singleton objects (as is a lot of Apple's UIKit). Games frequently employ singletons because you typically have a lot of central data in a game, like scores, health, weapons, etc that many of your objects need some knowledge of. You also typically have objects, like players, enemies, etc that need to notify the central dispatch of your app what they are doing so other objects in the game can react or adjust accordingly.
This is why many Cocos games use the technique you've shown here. It is not bad practice if you understand the risks of singleton programming. Basically, keep this in mind:
Whether you use a singleton-style technique or instead call up the parent using another method, you are essentially doing the same thing either way. It's probably better to directly reference the central game engine directly than rely on methods to derive it for you. I would not recommend using [self parent] as that can get hard to read and debug later when you first have to figure "who is the parent," instead a singleton access lets you know immediately who you are accessing.
A child should never retain its parent. You can reference the parent, but don't retain.
An alternative to the singleton approach here is to make an iVar in the child that points to the parent. But this is essentially the same idea, so to minimize the risks of a retain cycle, accessing the singleton is typically safer. If your iVar is not set properly, you could have a circular reference. The method you've shown here is not a circular reference.
Note that this particular code prevents you from using +(GameScene*) sharedGameScene method until after the GameScene has been initialized. This is what makes it a semi-singleton. Typically, this method in a singleton will be smart enough to initialize itself if it is not already initialized so that using this class method either returns or first creates and then returns the object.
Probably not an issue in Cocos since you will likely initialize the Game Scene before you do anything else, so it will already exist.
I'm guessing you're referring this part :
static GameScene* instanceOfGameScene;
+(GameScene*) sharedGameScene
{
NSAssert(instanceOfGameScene != nil, #"GameScene instance not yet initialized!");
return instanceOfGameScene;
}
This doesn't create a circular reference. Some might argue that's not a great practice to build your code this way, but that's a different discussion.
If the returning value from this function (the GameScene object) isn't referenced as strong property in some of GameScene children, it's ok.
You would have the case of circular reference if you had this in one of the children :
#property(nonatomic, strong) GameScene *mainScene;
// OR for non-ARC
#property(nonatomic, retain) GameScene *mainScene;
These would have kept the reference count for the GameScene object from getting to 0 and dealloc-ing.
Hope this helps.

Objective-C Multithreading and Data Containers

I have sort of a simple question. I am writing an Objective-C program with some multithreading. I have a global NSArray, and I add objects into that NSArray from a method that is called in a new thread. If the objects I add into that NSArray are new objects created in that method (local), will that create memory access and/or other issues or will the garbage collector be smart enough to keep those objects around until they have no more references? Also, if I want to an object into that NSArray, will that object be passed by reference or by value?
Can you add objects in NSArray? I guess you mean NSMutableArray.
NSMutableArray is NOT thread safe. So you may need to acquire a lock before trying to modify it. Though this will mostly dependent on how your threads are working on shared data.
NSArray or NSMutableArray will retain the objects that they contains. So after adding you can release the local copy.
The array will store the reference.
Hope it helps. In general multithreading is much more difficult than a single thread app. Please check Threading Programming Guide for the details. It may save you from many hazards.
There should be no problems with the design you're describing. All of your threads share the same memory space, so everything will work just fine. The memory management system will do "the right thing", but I recommend learning the retain/release method - there's nothing better than actually understanding what your program is doing.
Objective-C is pass-by-value only, just like C. That said, objects are only ever passed around by pointers in Objective-C, so you can think of it as always pass-by-reference in that sense.

cannot convert 'b2PolygonShape' to 'objc_object*' in argument passing

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/

Objective C Class or struct?

I have a class Song with properties Title, Key, Artist, etc. There are no methods. I loop through a database of song information and create a Song object for each, populating the properties, and then store the Song objects in an NSArray.
Then I thought, why not just have a struct Song with all those same properties instead of a class Song. Doing so would eliminate the class files, the #import Song line in the using class's .m file, and the need to alloc, init, release.
On the other hand, I'd have to put the struct definition in every class that might need it. (Unless there's some globally accessible location -- is there?) Also, can a struct be stored in an NSArray?
I would do it with a class. A struct cannot be stored in an NSArray (or any of the other container classes for that matter), unless you wrap it in a NSValue, which can be done but is a bit fiddly.
Plus, as you have pointed out, you have to define the struct somewhere. The normal way would be to define it in a header (.h) file just as for a class. So there's no 'gain' from a struct there.
You can't store structs in an NSArray (look at the signatures of its methods — they all take and return objects). But besides that, as I said in the answer to another recent question, putting objects in structs is just about always a bad idea. Objects need to be retained and released and structs don't have code associated with them to ensure that happens at the right times. This makes more sense as a model object.
It could go both ways but why not separate your concerns and keep it in it's own class file? Plus, doing so is more in line with the Single Responsibility Principle of SOLID. Why give your main class file another reason to change? Break it out.