I just installed the new version of Xcode/ios6. viewDidUnload is now depreciated.
In the apple doc,
viewDidUnload [...] Deprecated in iOS 6.0. Views are no longer purged under low-memory conditions and so this method is never called.
But numbers of apps are using this callback to release their properties, like :
- (void)viewDidUnload {
[super viewDidUnload];
self.recipientButton = nil;
self.connectButton = nil;
self.infoLabel = nil;
}
This was the best practice to release your IBOutlets.
So, first question:
What is going to happen these existing apps in iOS 6? Will they leak ?
and second one:
What is the new recommended way to release an IBOutlet property ? In dealloc method ?
For the first Question:
Your ViewController will receive didReceiveMemoryWarning method callback and you can nil out the view & other components in this method
For Reference Do Check WWDC 2012 video Session on EVOLUTION OF VIEW CONTROLLER, in case you haven't (I Believe they are available only for registered developers, but not sure).
Answer to your second one.
[object release]; in dealloc. No need to assign nil to object before releasing.
I recommend you to use weak property for the IBOutlets like
#property (weak) IBOutlet UILabel * labelText;
That way you don't need to do anything in dealloc. In iOS 6, simply ViewDidUnload won't call, iOS5 or earlier it is just call when memory warning have occur.
and second one: What is the new recommended way to release an IBOutlet
property ? In dealloc method ?
What is the "old" recommended way? You must always release retained instance variables in dealloc; it has always been this way and continues to be this way.
It was just that in viewDidUnload (which is only called for low memory) you could also set your properties to nil.
Related
I have setup a custom intent and it all seems to be working fine except that the handler is not being called. Siri responds as if everything was successful but I don't see anything in the console output and none of my breakpoints are triggering... Here is the handler...
#implementation IntentHandler
- (id)handlerForIntent:(INIntent *)intent
{
// This is the default implementation. If you want different objects to handle different intents,
// you can override this and return the handler you want for that particular intent.
NSLog(#"In handlerForIntent.");
if ([intent isKindOfClass:[TriggerSceneIntent class]])
{
return [SceneIntentsHandler sharedInstance];
}
return self;
}
#end
I have breakpoints at the if statement and both return statements. None of them are being hit. I also never see "In handlerForIntent" in the console log in xCode.
I'm guessing this is something fairly simple that I missed but I'm not seeing it. Welcome any suggestions?
I faced a same problem - handler wasn't called.
Finally I've found out, that although the project supports iOS 11.4, it initially set IntentExtension target to iOS 13. And my device, which I use for testing, has 12.4.
So my advice: check your deployment target for each target.
The watch app I am developing is not using ARC. And so I releases all the properties of objects in each interface in dealloc as below.
-(void)dealloc {
[obj1 release];
[obj2 release];
...
[super dealloc];
}
This causes crash when i close the interface (for example to go back to main interface). Why is this so?
Retains and releases need to be balanced in the context of your class. Probably you didn't retain when you assigned to one of those instance variables, and thus it's an over-release. You can try enabling zombies to catch the message to a deallocated instance if that's the case.
iOS 6 MKMapView seems to be using the tons of memory, when we starts zooming and playing around with the Map View in our application(for around 7-10 mins), When we come out of the controller which has MKMapView, its some how not releasing the total memory(I am using ARC in my App). I am allocating and initializing the MKMapView thru NIB.
Controller 1 -->Controller 2 (has MKMapView)
1.5MB -->40-60MB (I have used the Instruments to find out leaks, but of no use)
When i come back to Controller1 the live bytes seems to be 7-10MB, after every visit to controller 2 there is around 2-3MB of increment in the Live Bytes, after some time it crashes the application, in console it says "Received Memory Warning". can any one please help? If you need any more info please let me know. Thanks in Advance.
This is because of the way MKMapView works. There's an operation pending, so MapKit is retaining the MKMapView and it hasn't actually been deallocated yet. That isn't itself a problem. The problem is that it's still sending messages to your delegate.
The workaround is simple: As part of your view controller's cleanup set the map view's delegate to nil, which will prevent MKMapView from sending messages to it.
This is documented in MKMapViewDelegate Protocol Reference:
Before releasing an MKMapView object for which you have set a delegate, remember to set that object’s delegate property to nil. One place you can do this is in the dealloc method where you dispose of the map view.
Edit: Give Oscar an upvote as well, just below, who provided the documentation quote here.
Given ARC, I suggest this means you should set your map view's delegate to nil in your view controller's dealloc.
You can do some thing like this which resolves my issue . Change the type of map helps it too.
- (void)applyMapViewMemoryHotFix{
switch (self.mapView.mapView.mapType) {
case MKMapTypeHybrid:
{
self.mapView.mapView.mapType = MKMapTypeStandard;
}
break;
case MKMapTypeStandard:
{
self.mapView.mapView.mapType = MKMapTypeHybrid;
}
break;
default:
break;
}
self.mapView.showsUserLocation = NO;
self.mapView.delegate = nil;
[self.mapView removeFromSuperview];
self.mapView = nil;
}
-(void)viewDidDisappear:(BOOL)animated
{
[self applyMapViewMemoryHotFix];
}
I have in .h:
#property (nonatomic,retain) NSString *myString;
In .m:
#synthesize myString;
myString =#"Test";
Do I have to release it in dealloc?
Because sometimes my app crashes due to [myString release], not sure why?
As long as the property is defined with the "retain" attribute, it needs to be released in the dealloc.
ARC (Automatic Reference Counting) in modern Objective C has built-in garbage collection, so releasing and retaining are no longer necessary.
#property(nonatomic, retain) NSString *password;
-(id)init {
...
password=[NSString stringWithFormat:#"%#", [[NSProcessInfo processInfo] globallyUniqueString]];
OR
password=[[NSProcessInfo processInfo] globallyUniqueString];
}
My problem is that during course of execution at some random point the password object gets automatically released. Effect is same when i use either of the assignments. As soon as i put in a retain, the problem no longer exists. I'm sure there is no release of password object anywhere in the flow - as i mentioned it is in a singleton class. I also checked that the class instance is same even when the password object is released.
Any hints please!
You assign the iVar, not the property...
So as you don't use the setter method, your object is not retained.
Use the property instead:
self.password = ...
You could use...
password=[[NSString stringWithFormat:#"%#", [[NSProcessInfo processInfo] globallyUniqueString]] retain];
Also checkout Apple's doc on memory management. I would also set breakpoints in your code and see then your object gets released.