PDA

View Full Version : NSString, stringByStandardizingPath method




idelovski
Sep 11, 2008, 02:03 PM
This is my first post here, just started with Cocoa few days ago. There are
few ObjectiveC concepts that confuse me now and I think similar code is
going to confuse me even more in the future.

Here is the code from a Cocoa book and I want to know if this is a memory leak?

fileName = [fileName stringByStandardizingPath];

Documentation for stringByStandardizingPath (http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/stringByStandardizingPath):
Return Value - A new string made by removing extraneous path
components from the receiver. .. If any other kind of error is encountered
(such as a path component not existing), self is returned.

How am I supposed to handle that? Should I release fileName? Should I
compare old and new pointers? Maybe I should code like this:

- (NSString *)standardizePath:(NSString *)origFileName
{
NSString *newFileName = [origFileName stringByStandardizingPath];

if (origFileName != newFileName)
[origFileName release];

return (newFileName);
}

What if original string was created from string literal, like:

NSString *fileName = @"~/SomeFile.txt";

My background is in straight C where things look a bit more straightforward
than these oo concepts. ;)



Soulstorm
Sep 11, 2008, 02:24 PM
This is my first post here, just started with Cocoa few days ago. There are
few ObjectiveC concepts that confuse me now and I think similar code is
going to confuse me even more in the future.

Here is the code from a Cocoa book and I want to know if this is a memory leak?

fileName = [fileName stringByStandardizingPath];

Documentation for stringByStandardizingPath (http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/stringByStandardizingPath):
Return Value - A new string made by removing extraneous path
components from the receiver. .. If any other kind of error is encountered
(such as a path component not existing), self is returned.

How am I supposed to handle that? Should I release fileName? Should I
compare old and new pointers? Maybe I should code like this:

- (NSString *)standardizePath:(NSString *)origFileName
{
NSString *newFileName = [origFileName stringByStandardizingPath];

if (origFileName != newFileName)
[origFileName release];

return (newFileName);
}

What if original string was created from string literal, like:

NSString *fileName = @"~/SomeFile.txt";

My background is in straight C where things look a bit more straightforward
than these oo concepts. ;)

Objects returned from methods generally are autoreleased objects. That means that they are sent the message -autorelease (of course, in your methods you will need to do this manually). So, that means that this object will be released when the next autoreleasepool is released, and you will not need to release it yourself.

In the case where an NSString is created from a string literal, you will not release it, as this is a constant. Think it like that: If you were creating a C -style array like a constant ( char p[] = "hello world" ) would you call free() on it? No.

In your code, you are creating an error. The line "NSString *newFileName = [origFileName stringByStandardizingPath];" means that you are creating an object using dynamic allocation of memory (like if you are using malloc()) and you are creating a pointer that points into that object! So, since the original object is released automatically, the pointer that points to this object will end up pointing in nowhere, so you are not creating a memory leak.

However, you are releasing that pointer that points to that original object, so when the next autorelease pool is released, it will complain that there is nothing to release, since you did it before!

Bottom line: this code is OK:
NSString *str = [@"~/Dekstop" stringByStandardizingPath];

...and it doesn't create a memory leak.

Memory management in Cocoa is difficult for beginners, but I will tell you something that may help you:
Every object in Cocoa is a C struct that is allocated dynamically using something like malloc(). Don't forget that you are dealing all the way with pointers here. Memory management in Cocoa is like memory management in C with malloc() and free().

idelovski
Sep 11, 2008, 02:43 PM
Thanks for the quick answer. I think I see things more clearly now.

Soon I'll reach the 'Memory handling' chapter and maybe even learn to love ObjC.

Soulstorm
Sep 12, 2008, 04:06 PM
Thanks for the quick answer. I think I see things more clearly now.

Soon I'll reach the 'Memory handling' chapter and maybe even learn to love ObjC.

The way I see it, Objective C is great because Cocoa is great. Cocoa would be nothing without Objective C, and Objective C would be useless if Cocoa hadn't taken advantage of Objective C's potential.

You will never love Objective C. Objective C in command line application is useless, and does little that C++ doesn't do. It's syntax is complicated, and I rarely use it for command line applications. But it is the strength of Cocoa, and I love the way the language and the API are integrated.

idelovski
Sep 13, 2008, 12:33 PM
You will never love Objective C. Objective C in command line application is useless, and does little that C++ doesn't do. It's syntax is complicated, and I rarely use it for command line applications. But it is the strength of Cocoa, and I love the way the language and the API are integrated.

Wow. I am at the beginning of it and just hope things are better than you picture here. For one thing,
I like the fact that ObjectiveC lets me mix in regular C and it keeps it obvious which is which.

Anyway, I found the document (http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html) that explains all about the memory usage in ObjC and then I found
short version that sums up all there is to know: Technical Q&A QA1367 (http://developer.apple.com/qa/qa2004/qa1367.html).

Plus, I've learned about three different styles of setter methods (http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html) and I think that should be enough of
ObjC wisdom for this week.

Soulstorm
Sep 14, 2008, 04:03 AM
Wow. I am at the beginning of it and just hope things are better than you picture here. For one thing,
I like the fact that ObjectiveC lets me mix in regular C and it keeps it obvious which is which.

Anyway, I found the document (http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html) that explains all about the memory usage in ObjC and then I found
short version that sums up all there is to know: Technical Q&A QA1367 (http://developer.apple.com/qa/qa2004/qa1367.html).

Plus, I've learned about three different styles of setter methods (http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html) and I think that should be enough of
ObjC wisdom for this week.

What makes you rhink that I am describing things as being a mess? Did you start learning Objective C because you wanted to learn a new language to develop command line applications, or because you wanted to learn the Cocoa API? If your choice is the first, then you could have made a far better choice, like C++ or C#.

As for memory management, I should clarify something here. There are generally 2 ways of making a setter method. The first one involves the release of the previous object that a pointer points to, and then assigning the new pointer onto it and retain it. However, I should warn you that any changes to the original object (the one that is assigned to another object) will have immediate effect on the second object. That's because the two objects point to the same address in space (remember the basic principles of pointers in C?).

The second one is to release the old object, and then assign a new hard copy of the other object to it to ensure that changes to an object will not affect the other one. It's your choice, depending on what you want to do. Generally in Cocoa, we use the first approach, but in command line applications, I sometimes used the second one.

I also believe you are thinking wrong of Objective C. ObjC will not solve every programming problem. It's just the way to learn Cocoa. I don't know your programming background, but if you have programmed in C++, you would see that C++ command line applications are generally more easy to write than Objective C programs. Sure, C++ is more typesafe, and you lose some flexibility, but that doesn't matter a lot into small command line applications. And also, C++ has more control over low-level features than Objective C, which makes it better to get involved with low-level functions and write stuff such as game engines, and parts of the program that are specialized and that Objective C can't go. You will then use Objective C with COcoa to wrap the whole thing up into a GUI.

lee1210
Sep 14, 2008, 10:57 AM
Sure, C++ is more typesafe, and you lose some flexibility, but that doesn't matter a lot into small command line applications. And also, C++ has more control over low-level features than Objective C, which makes it better to get involved with low-level functions and write stuff such as game engines, and parts of the program that are specialized and that Objective C can't go. You will then use Objective C with COcoa to wrap the whole thing up into a GUI.

I'm not entirely sure what low-level features C++ can access that C cannot. Any valid C is valid Objective-C. Since you can also combine Objective-C and C++, if there was a C++ API you could still access it from Objective-C.

-Lee

idelovski
Sep 14, 2008, 01:30 PM
I don't know your programming background, ...

I already stated in my first post that "my background is in straight C", but I can elaborate on that. I've spent some 20 years with C on DOS, Classic Mac OS and in this century in Carbon and Win32. On several occasions I tried to learn and use C++, java and C# but that amounted to nothing except some wasted time. I had plans with GTK+ for this year, but this summer I changed my mind and two weeks ago I ordered that book by Hillegass on Amazon and it came this week. Some five years ago I bought Learn Cocoa & Cocoa in a Nutshell by JD Davidson, but never opened them until very recently.

I also believe you are thinking wrong of Objective C. ObjC will not solve every programming problem.

I am sorry if I came here as someone with strong opinions about Objective C and Cocoa. With only five days of experience with it any opinion I might have about it could actually be viewed as prejudice. ;)
I only have first impressions and so far they are positive.

Soulstorm
Sep 14, 2008, 03:48 PM
I'm not entirely sure what low-level features C++ can access that C cannot. Any valid C is valid Objective-C. Since you can also combine Objective-C and C++, if there was a C++ API you could still access it from Objective-C.

-Lee

Supposing we had OpenGL native support for Objective C. If you wanted to use objects, what language would you prefer for developing a game engine? C++ or Objective C? I would choose C++. It gives you more direct access to memory management and generally, it is accepted that C++ is for solving closed world problems, and ObjC for solving open world problems.

I already stated in my first post that "my background is in straight C", but I can elaborate on that. I've spent some 20 years with C on DOS, Classic Mac OS and in this century in Carbon and Win32. On several occasions I tried to learn and use C++, java and C# but that amounted to nothing except some wasted time. I had plans with GTK+ for this year, but this summer I changed my mind and two weeks ago I ordered that book by Hillegass on Amazon and it came this week. Some five years ago I bought Learn Cocoa & Cocoa in a Nutshell by JD Davidson, but never opened them until very recently.

Well, you will find things difficult at first, since you not only learn a new language, but also a new way of programming (Object Oriented Programming). And in Cocoa, you can't program without OOP.

lee1210
Sep 14, 2008, 04:57 PM
Supposing we had OpenGL native support for Objective C. If you wanted to use objects, what language would you prefer for developing a game engine? C++ or Objective C? I would choose C++. It gives you more direct access to memory management...


There's a lot actually going on with this question, so I can't really answer it directly. OpenGL is a C API as far as I know, and Objective-C does have direct access to any C library, so no supposing is required.

I would never try to develop a 3D game engine with the number of quality open source engines already available, but if I were to I would choose C++ because its runtime libraries are mature on every platform. I wouldn't bother building an engine that was only supported well on one platform.

In regard to memory management, I am assuming you mean in terms of Object deallocation, due to the Objective-C run-loop. In near-realtime systems, like perhaps a game engine, this can be a big deal. As is the case in any discussion of languages, I'll note that I think most modern languages are on even ground when it comes to language design, library availability, ease of use, etc. but advantages and disadvantages arise when you start talking about a specific problem domain.

Most shortcomings can be coded around if needed, as well. In the example of a game engine, you could write the time-sensitive, cpu-intensive, memory-intensive portions in C, giving you total control over memory usage with free and malloc, then write higher-level things like a HUD using Objective-C objects that are easier to manage.

I'm really not sure how the thread took this sort of turn, and apologies for going so far OT... I was really just responding to the bit about Objective-C not having access to low-level things, and my assumption that Soulstorm meant things like APIs and system calls, rather than details of the runtime's Object management.

-Lee