Objective-C tutorial?

Member
Posts: 28
Joined: 2008.06
Post: #31
I added debug lines, and op isn't nil before that statement is run. Could there be a problem if the string doesn't have a decimal point?
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #32
Doubt it, but anything is possible. You'll have to start breaking it down. Replace op's return value with an actual float, like:

an = 123.432f;

If it still goes bad access then op is off the hook (presumably). Do the same for the other instance variables you're sending messages to. Once you find out for sure which message is causing the fit then you can start backtracking through your code on it.
Quote this message in a reply
Member
Posts: 28
Joined: 2008.06
Post: #33
I think it's op, because when I replace op with 3.14159265, it doesn't crash.
Lines that I think might be the problem:
op = [op initWithString: @""];
op = working;
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #34
I should caution that just because an instance doesn't come up nil doesn't mean it isn't garbage. Seeing that it is nil just definitely confirms that it's garbage. No real good way to tell otherwise. Like I mentioned, an instance is represented as a pointer, and that pointer could be changed to anything if you aren't careful.

It's getting hard to say exactly what's up without seeing the rest of your code. What is "working"? Is "working" retained?

When you do:

op = [op initWithString: @""];

Remember that op isn't retained because it is being created with a convenience method which autoreleases it... i.e. it isn't being created with op = [[NSString alloc] init], which is automatically retained. (anything [[alloc] init] is automatically retained, otherwise it is usually considered to have been autoreleased upon creation)
Quote this message in a reply
Member
Posts: 28
Joined: 2008.06
Post: #35
"working" is the string being edited currently, and "op" is the stored string.
I'm trying to make a calculator. "working" is retained, and I fixed it so that "op" is retained, as far as I know. Should I post the full source-code?
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #36
computergeek6 Wrote:Should I post the full source-code?

Yes, that would be helpful. If it's too large to reasonably post here (or you're not comfortable posting it here for whatever reason), you can email it to me at anotherjake +AT+ mac.com instead.
Quote this message in a reply
Member
Posts: 28
Joined: 2008.06
Post: #37
Full .m file: http://www.mediafire.com/?brcgcdgxlzg
It's not really commented, because I usually do that once the code is done.
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #38
Okay, got the file. Lots of retain problems. Definitely need to study up on the retain/release thing a bit more. For example, when you do something like this:

working = [working stringByAppendingString: @"0"];

You *must* retain it because the new "working" is being created by what is called a convenience method (i.e. not alloc inited). You should be doing something like this instead:

Code:
- (IBAction)zero:(id)sender {
    NSString  *newWorking = [[working stringByAppendingString: @"0"] retain];
    [working release];
     working = newWorking;
    [self updateDisplay];
}
Quote this message in a reply
Member
Posts: 28
Joined: 2008.06
Post: #39
why do you need the extra NSString?
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #40
Well you don't *have* to have it I suppose, but it's a standard pattern in Obj-c programming to create a new separate object, release the old one, and then set it to being the new one.

However you choose to do it, a new string is created by a convenience routine, and must be retained, and the old one must be released.

[edit] you could do it:

Code:
- (IBAction)zero:(id)sender {
    [working release];
     working = [[working stringByAppendingString: @"0"] retain];
    [self updateDisplay];
}

But notice that the old one is released and the new one retained. That's the important part. Yes, you are creating a new string. That's the way it works.
Quote this message in a reply
Member
Posts: 28
Joined: 2008.06
Post: #41
Thanks. Also, how do you know which routines are convenience routines?
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #42
If an object is created with an alloc-init, like:

SomeClass *myObject = [[SomeClass alloc] init];

Then it is retained for sure. If it wasn't created by an alloc init, then it is likely autoreleased, although there are exceptions from time to time, and documentation should point that out. With Apple's stuff it is almost always autoreleased if you didn't explicitly create it with an alloc init. Again, there are exceptions to how you should handle retains and releases for particular objects, like NSTimer should only be released with an invalidate message... Gotta check the docs.

With third-party code, you never know exactly what you get unless you read their docs or read their source. For instance, I am notoriously bad about returning retained objects in my custom inits rather than autoreleased objects, as I should. Generally though, again, you should expect that if you didn't create it with an alloc init, it is likely autoreleased.

It takes some practice and experience to understand the retain/release thing, but it is crucial to understand it. The number one thing to keep in mind is that it is going to be the source of the vast majority of your bugs for a while. If you get a mystery bug, assume it's a retain/release problem first thing!

Check your retains by sending objects the retainCount message if you are in doubt. Unfortunately retainCount doesn't tell you if a retain is autoreleased, but at least it can give you some indication of what's up.

[edit] bedtime approaches...
Quote this message in a reply
Member
Posts: 28
Joined: 2008.06
Post: #43
I'm going to buy a tutorial e-book soon, so hopefully I'll pick up something from that. I'll post the source again when I think I've gotten the retain problems sorted out.

PS: Thanks for being so helpful, even though I'm just a noob.
Quote this message in a reply
Apprentice
Posts: 11
Joined: 2007.02
Post: #44
I'll throw in a suggestion that maybe, if you're just getting started, you might want to turn on garbage collection in your application. It's a build setting which is off by default. When that is on, you don't have to concern yourself with retain/release and code just becomes much easier to write.

IMO, anyway. I know there are many opinions on both sides of the garbage collection issue. Smile
Quote this message in a reply
Apprentice
Posts: 11
Joined: 2007.02
Post: #45
Hey computergeek,

If you'd like, send me an email to willem at wantonhubris dot com with your mailing address and I'll send you my second edition of Hillegass's book. I bought the third edition so this second edition is just gathering dust at this point.

Some of the interface builder stuff may be out of date but it's still a great introduction to how everything works in Objective-C/Cocoa.
Quote this message in a reply
Post Reply