AnotherJake Wrote:You should study up more on Obj-C memory management.

I've been a long-term C++ programmer, and have been programming Objective-C for the past year or so. I've come into contact with many memory management schemes over the years... let's just say that manual reference counting is very error prone.

With well-defined ownership documentation, the blame for releasing/retaining in the wrong place falls squarely on the shoulders of the programmer. Unfortunately,

a) most APIs I've seen so far do not even begin to mention ownership, which is just very, very sad, and
b) when you have to retain/release manually, it's fairly easy to not pay attention and do something wrong.

No, autorelease isn't the solution to the problem. It helps reduce refcounting issues, but adds the unpredictability of garbage collection.

With smart pointers in C++ (see boost's here as an example, but you can easily roll your own), ownership is quite easily documented in the code (as opposed to comments), simply by your choice of smart pointer. At the same time, each object's lifetime becomes a lot more predictable than it is in Objective-C.

I've got to say, I can't help but reply that many Objective-C people probably don't really understand the value of RAII in combination with stack objects, the basis for any smart pointer implementation.

TomorrowPlusX (another member here) is a major advocate of boost's smart pointers, so when messing around with his code I've had a chance to be exposed to it, and I have to say that smart pointers seem pretty slick from what I've seen.

The reason I suggested that you study up more is because you said "I'm actually quite annoyed with Objective-C memory management. Bjarne's language is just much more thoughtful than Brad's language." On the surface, that comparison doesn't make sense to me if you are as familiar with C++ and Obj-C as you claim you are. Memory management in Objective-C is the way it is because it is Objective-C, not C++.

Quote:I've got to say, I can't help but reply that many Objective-C people probably don't really understand the value of RAII in combination with stack objects, the basis for any smart pointer implementation.

You're probably right, but I can't say that I see how suggesting that "many Objective-C people probably don't really understand the value of <insert term here>" will make you many friends in the Mac community since we all pretty much have to use Objective-C to at least some degree whether we like it or not, or whether or not we understand the value of RAII. One can easily discuss RAII without involving the relative level of ignorance you believe "many Objective-C people" possess.

Memory Management Programming Guide for Cocoa Wrote:You own any object you create.
You "create" an object using a method whose name begins with â€œallocâ€ or â€œnewâ€ or contains â€œcopyâ€ (for example, alloc, newObject, or mutableCopy).

As ThemsAllTook obliquely says, there is no need for any Cocoa API to mention memory management, because *all* Cocoa APIs share a single convention.

Unlike C++.

Just because ObjC is different, doesn't mean it's worse. Remembering the ObjC rules and calling retain and release in the few places that are required is not difficult; overreleases are generally easily caught with NSZombieEnabled, and underreleases are generally easily caught with leaks.

IMO this is a vastly superior situation to C++ where you must have detailed knowledge of the ownership rules of each individual object, and as soon as there is more than one reference to an object, you end up in a world of hurt (or using "smart pointers" or some other ad-hoc reference counting system anyway).

In my experience, managing ownership in C++ is a major part of program design that is simply a non-issue in Cocoa, and a major source of difficult crashes, which is seldom the case with Cocoa.

Boost's smart pointers are essentially just reference counting with a pretty wrapper. I don't see them much superior to ref counting, as you still have to remember to use smart pointers. So, in effect, you're having to do about half as much work, by only having to declare a smart pointer when in ObjC you'd have a retain/release pair.

But, with autorelease pools (which you can put in place yourself, btw) you don't have to do anything for most local variables, so again the added benefit of smart pointers is diminished.

And last, as OneSadCookie said, *all* ObjC frameworks use the same conventions, so working with random 3rd party stuff is seamless, in that respect.

And really last, ObjC 2.0 has garbage collection, so memory management is mostly a non-issue.

I was reading this thread for the last couple of days over and over again.. Unfortunately I still have a problem with my render runloop.

What I have now is a RenderEngine class which creates the window/glView as in CrashLanding example but without the usage of any nib files.
The RenderEngine actually creates a RunLoop class instance which in turn has a while loop within a new thread. There is a definition of a delegate which points to the RenderEngine instance and the RunLoop delivers notifications with delta time to the delegate. The runLoopInit method in the delegate (RenderEngine) is used to initialize the window/glView (thus everything related to drawing is done from a totally separated thread. This might be my problem). There are a couple more delegate methods: runLoopBeforeHook:/runLoopAfterHook: and the musthave one is the runLoopActionHook: method. In my case (RenderEngine) I use the before/after hooks to do the buffer switching in OpenGLES and the action hook is used to do all my rendering in between.
To me it looks like a very straightforward architecture which should work just fine but for some reason it does not. I am very new to OpenGL (any, including ES).
The code which fails is actually the [context presentRenderbuffer:GL_RENDERBUFFER_OES] line. It used to work when I had everything in a single thread with NSTimer. Now when I ported everything to threads/loops I got this problem. It doesn't crash or anything.. It just returns false and hangs for 1 second everytime I call it.

godexsoft Wrote:thus everything related to drawing is done from a totally separated thread. This might be my problem

I did a lot of testing and made lots of changes to things and even removed Threading but have still the same problem. It's obviously not in the multithreading. It looks strange to me but I guess the problem is with memory or maybe somewhere in AutoreleasePool (or my usage of it).

When I init the RenderEngine i'm setting up the UIWindow and make that key and visible. At this point (in the same method) I can add UILabel to it and that works. However the glView is constructed in the callback runLoopInitHook which constructs glView and adds it to the window as usual. But if I try to add the UILabel at this place it fails.. to me it looks like the window object is not really accessible at this point. Is that normal? Do I have to add all my views to the window object at once or can one usually dynamically manipulate UIWindow subviews just as you can manipulate on any UIView?
In my understanding I'm very close to fix this problem already but any input will be highly appreciated.

First of all - sorry. I had to read some more about OpenGL before I start asking stupid questions.
Anyway I found the solution to my problem. The problem was in 1) OpenGL which doesn't like to be accessed from different threads 2) in iPhone window/view management which didn't like that I tried to to add glView into the window in another thread.

Basically I have all my rendering actions performed on the main thread now although the runLoop for rendering uses it's own thread for the while loop. With both Render and Logic runLoops setup I have about 65-80 FPS in both on a simple scrolling text screen in my game (Credits screen). The Logic uses a separate thread for all calculations.
I just wanted to let you know that the problem is fixed so you guys don't have to spend time on helping me out. Thanks anyway!

Quote:Unless I'm mistaken, the autorelease pool will release objects in between events making it very predictable.

In my book, that's unpredictable, because you can't know when an event will fire. Any message you send may result in the current NSRunLoop advancing, so the only situation in which you are safe from objects disappearing is in blocks which send *no* messages whatsoever. That includes alloc/create/copy messages (been mentioned before).

Quote:The reason I suggested that you study up more is because you said "I'm actually quite annoyed with Objective-C memory management. Bjarne's language is just much more thoughtful than Brad's language." On the surface, that comparison doesn't make sense to me if you are as familiar with C++ and Obj-C as you claim you are. Memory management in Objective-C is the way it is because it is Objective-C, not C++.

I didn't say that, but no matter. I parse this as you saying "You can't compare memory management in Objective-C and C++ because they're different languages", when the original author compared the languages on the merits of their memory management model.

Quote:You're probably right, but I can't say that I see how suggesting that "many Objective-C people probably don't really understand the value of <insert term here>" will make you many friends in the Mac community since we all pretty much have to use Objective-C to at least some degree whether we like it or not, or whether or not we understand the value of RAII. One can easily discuss RAII without involving the relative level of ignorance you believe "many Objective-C people" possess.

That statement was made in reply to the suggestion that one should study one form of memory management, and meant to suggest that people should study RAII in C++. RAII doesn't exist in Objective-C, C, Java, Python, Perl, or any other language that I know well enough to say this offhand - at least not in a way that would allow one to create smart pointers of the form I've mentioned.
While many developers know more than one language, most don't know a large number very well. C++ is just (un)popular enough, that relatively few people know it very well, unless they happen to develop in it most of the time. Few members of the Mac community will do so, as most will develop primarily in Objective-C (or possibly AppleScript, I don't know). So I think it's a reasonably fair assumption that not many Objective-C people understand a feature of a language they rarely use in depth.
This is in no way a value judgement, nor does "many" extend to all Objective-C people. So please don't twist my words to suggest that I set out to aggravate or insult people.

Quote:Boost's smart pointers are essentially just reference counting with a pretty wrapper. I don't see them much superior to ref counting, as you still have to remember to use smart pointers.

There are very few situations where *not* using smart pointers is a good idea. There's not much to remember with them - you just need to decide on the memory management semantics once, when you declare a variable. In all use-cases except declaration, they pretty much free you from thinking about memory management. If you try to do something that won't work with the memory management semantics selected during declaration, your program won't compile (in nearly all cases).

Quote:You own any object you create.
You "create" an object using a method whose name begins with â€œallocâ€ or â€œnewâ€ or contains â€œcopyâ€ (for example, alloc, newObject, or mutableCopy).

Ownership is closely tied to the lifetime of objects. I must apologize that I often lump them together into the same thing. That is, if you are not the owner of an object, you must know it's lifetime in order to safely dereference any pointer to it. Documenting this "largely by naming convention" works for single-threaded programs where all you need to worry about are memory leaks/growths, but in multi-threaded environments, it means the life and death of your program.