Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
This may be a very simple answer,but I cannot the solution anywhere. I have this object called board that gets passed into a method. I want to change the state of the board inside the method but not affected the board itself. Here is a very simple version of the code that I attempted so far:
- (int) getMove:(Board*)board {
Board* tempBoard = [[Board alloc] initSize:3];
tempBoard.slots = board.slots;
[tempBoard replaceIndex:5 withMark:#"X"];
return 1;
}
If I were to call this method with a board object X, X has the changes made from that method. I'm a noob at pointers so I'm thinking that is the cause of this.
If want to prevent the board to be mutated, you should make the Board class immutable, i.e. not exposing any public method to change its internal state.
If you need also the mutable version, you can have a subclass like MutableBoard which exposes the methods to mutate the object.
So in the end you will be able to do
- (int)getMove:(Board *)board {
[board makeMove]; // compiler error!
return 1;
}
and
- (void)doSomethingOnTheBoard:(MutableBoard *)board {
[board makeMove]; // ok!
}
I would also suggest you implement -mutableCopy on Board in order to support the creation of a mutable instance of it.
Bottom line, you just need to follow the same API design as NSString, NSArray, ... which are immutable, with an immutable subclass (NSMutableString, NSMutableArray...)
Apple has a great guide to the concepts of objects mutability you can read.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Ive searched around and can't find any answers that aren't related to C++, which isn't the exact same thing. I have a game and I keep an NSMutableArray of my sprites for certain categories because there are too many of them and they appear/dissapear too often to keep references to every single one of them, and also the number of them varies. so they are stored in an array.
In my didBeginContact method I grab the contact.bodyA.node object and pass it into a mehtod I've written called getSprite which enumerates over the array of objects I have, finds the one that matches and returns that one as an SKSpriteNode so I can use SKSpriteNode-specific methods such as animateWithFrames and such. However, I use this method pretty frequently and I'm wondering if doing something like:
SKSpriteNode *sprite = (SKSpriteNode*)[contact.bodyB.node parent];
Is acceptable as well, and then just using that pointer to refer to my object. It works, but I don't know if it will cause memory leaks or other problems. Any suggestions? (the reason I used the parent method is because the sprite I'm actually after is the parent of the one involved in the collision).
I assume you're using ARC. The local pointer to the object is a strong pointer by default, since you didn't specify anything differently. So that object is guaranteed to not be destroyed during the scope in which your local sprite pointer exists. It will not maintain a strong reference beyond that scope. The NSMutableArray also maintains a strong reference to to the objects it contains, so while they are in that array, the objects will not be destroyed.
As far as memory leaks go, this shouldn't cause any problems. It should also be more performant since it's a direct link back up to the sprite, rather than iterating and searching for the correct sprite. I don't see any reason why you couldn't do that, besides the fact that is might affect future plans for your game since the parent relationship of the object becomes part of the logic when is probably shouldn't be, but if you centralize that code so it's easy to change if you ever change the hierarchy of your sprites it should be fine.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I want to be able to, let's say, run a NSURLConnection post and download like this:
NSString *data = [Server post:para1, para2, para3];
I'm pretty sure that I have to write a class containing the delegates of NSURLConnection and of course the function called post initiating the NSURLConnection and returning the downloaded string.
The whole problem is that I don't know how to do this correctly. I've tried adding a class called Server with the delegates and such, and then making the function post public. Afterwards, the post function was not able to access the delegates and variables in the class. Furthermore, the post function had no way to return the string, since it was first known in the - (void)connectionDidFinishLoading:(NSURLConnection *)connection.
Can you please give me a hint how to make a class, that can HTTP POST to a URL and return the string and be run with only one or a few lines?
For a synchronous URL request (preferably in a non-main thread) you can use the
sendSynchronousRequest:returningResponse:error:
class method of NSURLConnection.
You could achieve this in two ways, one would be to have a custom delegate which gets called when the connectionDidFinishLoading has finished or you could provide your Server method a block callback which gets called when it is complete. Blocks are a bit confusing to start with but are a very good tool to know how to use.
Have a look at Blocks (Apple Doc)
Bock Tutorial
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I was trying to learn how to use properties in iOS programming.
I just want to check with people here if what I got is right?
Say I have a property
#interface Person : NSObject
#property NSString *firstName;
#end
in implementation
#implementation XYZPerson
#synthesize firstName;
...
#end
By this,
a) an instance variable named: firstName is created
b) whenever I want to use property inside my class, I call self.firstName (or setter/getter)
c) I can initialize the property in the init method like this:
-(id) init {
...
self.firstName=#"SomeText";
...
}
I believe the points I mentioned above, are correct, right?
What you say is pretty much correct although you are missing a few things from your #property declaration. You need at the very least a property attribute like strong or copy or assign. For strings which might be mutable, we generally use copy to ensure the string can't be modified from under us. So #property (copy) NSString *firstName. See this answer for more details about this.
Most people use nonatomic as well to improve performance by disabling thread synchronization in the generated getters/setters. See this answer for more information.
Some people recommend against using property accessors in the init method (preferring direct ivar access) because subclasses might have overridden the setter/getter and might not work correctly until the object is fully initialized. Practically speaking you very rarely need to worry about this so a lot of people ignore this advice.
With the latest version of Xcode you also don't have to add the #synthesize manually - an underscore-prefixed instance variable (_firstName in your example) will be synthesized for you automatically.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm new with Objective C and am not an uber programmer anyway but one thing I find odd is that it won't throw errors sometimes when objects are declared not initialized.
I just ran into this again - I had some setup stuff to be done in so I put it in an init function - but the class is a UIViewController that is wired up in the storyboard. So init was never called - and that's my error - (lots of NSObject derived classes in the project and I rushing and just tossed that in to test some things).
But my methods that were making calls to the instance that was supposed to have been set up in int didn't throw errors - it just that the values I was expecting were nil.
Isn't that sort of odd that that sort of stuff would fail silently?
You've got two separate issues here, both quite common for beginners.
Your init was never called because it's the wrong method entirely. It's not the designated initializer for a view controller, and in any case a view controller from a nib or storyboard gets initWithCoder:. So it's up to you to have a sense of what method will be called and when.
Messages to nil return nil with no error. This is a deeply entrenched feature of Objective-C and isn't going to change. There is often quasi-religious debate about it, and there are some clever ways around it, but that's neither here nor there really. Basically it's up to you to use lots of NSLog and lots of nil-checking (NSAssert is a great thing to use for this), especially during early stages.
Not odd at all. That's how Objective-C has always worked. Messages to nil simply do nothing.
It is strange, but that's how Obj-C was designed. Actually, from Obj-C perspective, the code did not fail (silently). Everything was correct.
In Obj-C you can alwyas send messages to ("call methods on") nil.
init is just another message ("method"), not a constructor. It's not needed to create and use an object. You can understand Obj-C only as a thin layer over C language. C language won't report if you haven't called a function on a struct, either.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Today, I got a link to a long list of coding guidelines, proclaiming to be "code commandments". A good read, and full of new insights to me. Among the list, somewhere along 25% of the scrollbar, I come across something new to me: Implicit data member creation.
Although every tutorial, book and video I've read or watched about Objective-C always performs the triad of NSNumber *number | #property NSNumber *number | #synthesize number, these commandments now tell me I can simply omit the first step (data member declaration in the interface) because #synthesize will create one on the fly. Say what!?
With a little disbelief I deleted several of my data member declarations, and indeed, my app still works like a charm. Less typing, less reading, less chance for typos.
Sounds to me like a win-win-win, but is it really good practice?
I'm asking this question out of pure disbelief that all the tutorials, books and videos are teaching the wrong lesson, at least too much of it, or that I've been not paying attention in class...
Cheers,
EP.
Edit: Although I copied the expression "data member" from the linked post, it is more commonly described with the word "ivar", just a good one to have in here for search friendliness. This also takes care of my former confusion over property/ivar/member naming :).
Synthesized instance variables are a feature of the modern Objective-C 2.0 runtime. This means they're available on x86_64, on ARM, and as of Xcode 3.2, on the iPhone Simulator. It means exactly what you suggested - you can omit the ivar declaration, and the #synthesize line will generate the ivar for you. The performance of this is exactly the same as declaring the ivar explicitly, but it has the very important benefit of not polluting your header file with private implementation details.
I have begun the practice of removing synthesized properties from the Objective-C classes I create. The primary reason for this is because there is a distinct difference between:
self.myNSObject = [NSObject new];
and
myNSObject = [NSObject new];
Specifically, if myNSObject is declared as a #property(retain, ...) the former line will result in a retainCount of 2 while the latter will result in a retainCount of 1. This means that unless you are extremely careful about every assignment to myNSObject you run the risk of getting your retain/release balancing wrong.
The other reasons you specify are also very valid. There is a lot going on in the synthesized routines that my brain doesn't account for when I'm reading the code I've written, so a lot is taking place behind the scenes that I'm not thinking of yet am accountable for. It's for very a similar reason I've abandoned Apple's Interface Builder.