Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.
In all honesty using performSelector:withObject:afterDelay: to call autorelease looks like it almost has to be an error.

ok, why? I have not done it my self but got the advice from other people having problem with the mapkit. The problem is that dealloc in the viewcontreoller may be called before the map is done loading and that will lead to a crash. So you have to delay the release some how. It seem to work though in my app and I have used it in a navigationcontroller app aswell without any problems. What would you suggest as alternative? And why is it an error?

MACloop
 
Hello,
I have struggled with this before and I hope that I have it correct now? The issue is about viewDidUnload and what variables to release, set to nit etc in this method. As I understand a memorywarning will lead to this method and afterwards the view will be loaded again. So, the variables I have released etc are all allocated or retained or IBOutlets... I have set some comments in the method inorder to show how they are retaiend/allocated.
So, what do you think?

The documentation has a section that tells you where to initialize and release your memory objects: Managing Memory Efficiently.

You are correct that a low memory situation will trigger the viewDidUnload method and you're supposed to release as much memory as possible in that method, but it should only be objects that you can later recreate in the viewDidLoad method.
 
The documentation has a section that tells you where to initialize and release your memory objects: Managing Memory Efficiently.

You are correct that a low memory situation will trigger the viewDidUnload method and you're supposed to release as much memory as possible in that method, but it should only be objects that you can later recreate in the viewDidLoad method.

Thanks for the comment! Yes I know about this - what suprised me was the problem with dealloc ie that you cannot release any objects in the viewDidUnload method without the risk to have them overreleased later on. I though that the viewController did not call dealloc when the viewDidUnload was called... This means that I have to look if the variables are exsisting before I kill them...
 
ok, why? I have not done it my self but got the advice from other people having problem with the mapkit. The problem is that dealloc in the viewcontreoller may be called before the map is done loading and that will lead to a crash. So you have to delay the release some how. It seem to work though in my app and I have used it in a navigationcontroller app aswell without any problems. What would you suggest as alternative? And why is it an error?

MACloop

I have not used MapKit for anything, perhaps this is a possible solution for that. As I said it just looks like it has to be wrong: it looks like an inelegant hack around a problem instead of tackling it "correctly". If it works right now that's great but if your app suddenly starts crashing as the delay is 0.1 seconds too short how will you know? The crash could happen in any semi-random looking place and be difficult to track back to here.

If you need to delay releasing that object until the map has finished loading then you should (I think) hold your deallocation until this delegate method fires then dealloc. That way you know 100% for sure it's happening at the correct time.
 
I have not used MapKit for anything, perhaps this is a possible solution for that. As I said it just looks like it has to be wrong: it looks like an inelegant hack around a problem instead of tackling it "correctly". If it works right now that's great but if your app suddenly starts crashing as the delay is 0.1 seconds too short how will you know? The crash could happen in any semi-random looking place and be difficult to track back to here.

If you need to delay releasing that object until the map has finished loading then you should (I think) hold your deallocation until this delegate method fires then dealloc. That way you know 100% for sure it's happening at the correct time.

Ok, thanks! Because this is a "well-known-apple-bug" I hope it will be dissapearing in some update in the near future. But I give you right on that - it is not 100% safe. Anyway, the rest is ok? Is it ok to look if a variable is not nil in both viewDidUnload and in dealloc?
MACloop

EDIT: ups that delegate method is new I think.... I have to try it out!
 
Ok, thanks! Because this is a "well-known-apple-bug" I hope it will be dissapearing in some update in the near future. But I give you right on that - it is not 100% safe. Anyway, the rest is ok? Is it ok to look if a variable is not nil in both viewDidUnload and in dealloc?
MACloop

EDIT: ups that delegate method is new I think.... I have to try it out!

Yes, I think it's OK to potentially dealloc in both places. I suspect that it should not be possible to reach the view controller dealloc before viewDidUnload runs I think it's prudent to allow for that.

The delegate method claims to have been there since 3.0 but as I've never used MapKit I can only go by the documentation!
 
Yes, I think it's OK to potentially dealloc in both places. I suspect that it should not be possible to reach the view controller dealloc before viewDidUnload runs I think it's prudent to allow for that.

The delegate method claims to have been there since 3.0 but as I've never used MapKit I can only go by the documentation!

Ok, then I will go for the approach with checking if a variable is nil or not.

hmm... yes the method is not new... I have to investigate it but I suppose it does not solve my problem, because it is a bug in the framework. I thought the newest update had come with some new goodies on this issue....
Thanks for the hints!
MACloop
 
Let me try and clear is up for you.

On top of the normal memory management rules, the following rules apply:

1. If your IBOutlets are properties with the 'retain' keyword, then it is down to you to ensure they are released when the view is unloaded. That is because your subviews are being retained twice. Once, by its parent view and once by your controller. When the parent view is unloaded, it will relinquish it's ownership of the subviews but its down to you to make sure your controller does too, in viewDidUnload.

2. The advised way of doing this is to both release and nullify the pointer otherwise you may leave dangling pointers to deallocced objects. You can do this with one line but be aware of any side effects if you have overridden any of your property setter methods.

Code:
- (void)viewDidUnload
{
  [super viewDidUnload]

  self.somesubview = nil;
}

3. You should also release your instance variables directly in dealloc as usual. There is no need to check if they are nil, just call release. It is safe to call release on nil (that is why you set your properties to nil above instead of just releasing them).

Hope that helps.

A small aside, Im still baffled by people who resist Interface Builder and there is nothing worse than inheriting a codebase that doesn't use nibs. Writing all of your view initialisation, configuration and layout in code buys you little to nothing and results in a codebase that is harder to maintain. Embrace IB. Apple recommend you use it for good reason and Im happy to see it even more tightly integrated with Xcode in v4. There are times when manually writing view code makes sense but 80% of the time you should just let IB take care of the tedious boilerplate for you.

If your gut is telling you to avoid Interface Buidler, for whatever reason, your gut is wrong. This isn't one of those cases where there's more than one right way and it's purely a matter of personal preference. Interface Builder is clearly the preferred way and with very good reason: it makes your applications faster to create and easier to maintain. —Jeff LaMarche
http://iphonedevelopment.blogspot.com/2009/10/dont-fear-interface-builder.html

This isn't really a dig at robbieduncan because he isn't the only person I've come across who tries to resist using Nibs but honestly, all you are doing is creating more work for yourself and costing your clients time and money, and obfuscating the interesting code with unnecessary boilerplate.
 
So I have implemeted as I wrote yesterday and it seem to work out. One more question:
When a memory warning is sended, the actual view is not changed, but the other views (I use a tabbar) are reseted and load again. Why is that?
MACloop
 
Let me try and clear is up for you.

On top of the normal memory management rules, the following rules apply:

1. If your IBOutlets are properties with the 'retain' keyword, then it is down to you to ensure they are released when the view is unloaded. That is because your subviews are being retained twice. Once, by its parent view and once by your controller. When the parent view is unloaded, it will relinquish it's ownership of the subviews but its down to you to make sure your controller does too, in viewDidUnload.

2. The advised way of doing this is to both release and nullify the pointer otherwise you may leave dangling pointers to deallocced objects. You can do this with one line but be aware of any side effects if you have overridden any of your property setter methods.

Code:
- (void)viewDidUnload
{
  [super viewDidUnload]

  self.somesubview = nil;
}

3. You should also release your instance variables directly in dealloc as usual. There is no need to check if they are nil, just call release. It is safe to call release on nil (that is why you set your properties to nil above instead of just releasing them).

Hope that helps.

A small aside, Im still baffled by people who resist Interface Builder and there is nothing worse than inheriting a codebase that doesn't use nibs. Writing all of your view initialisation, configuration and layout in code buys you little to nothing and results in a codebase that is harder to maintain. Embrace IB. Apple recommend you use it for good reason and Im happy to see it even more tightly integrated with Xcode in v4. There are times when manually writing view code makes sense but 80% of the time you should just let IB take care of the tedious boilerplate for you.


http://iphonedevelopment.blogspot.com/2009/10/dont-fear-interface-builder.html

This isn't really a dig at robbieduncan because he isn't the only person I've come across who tries to resist using Nibs but honestly, all you are doing is creating more work for yourself and costing your clients time and money, and obfuscating the interesting code with unnecessary boilerplate.

Wow! Thanks alot! Your answer is perfect! I am sorry I did not give you feedback earlier - I just saw it! Very nice explanation!
MACloop
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.