Memory is not released under ARC - ios

I have an app with a parent View Controller. It has some buttons and when one of them is clicked it presents a Modal View Controller (using XIB). The code I use to present and dismiss the Modal VC is :
iPadViewController *iPadVC = [[iPadViewController alloc] initWithNibName:nil bundle:nil];
[self presentViewController:iPadVC animated:YES completion:NULL];
and to dismiss :
-(IBAction)Back:(id)sender{
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
So the problem is, when I dismiss it, it does not release any memory. And if I present it 3/4 times it crashes. I am using ARC, never had similar problems because I tough that ARC did all the memory management job.
I do have some backgrounds that need a lot of space and they are not getting released either. I tried :
[backgroundImage removeFromSuperview];
backgroundImage=nil;
The memory does decrease using this code, I'm not sure if the image was released because the next time I press the button the memory increases to almost 300mb and terminates due to "memory pressure". If the VC was released it would work fine because it only uses 160mb on the iPad and 65mb on the iPhone. Also, My image is selected through the Xib utilities :
And I tried to use Xcode instruments and it does not show any leak (!) but it does show that the allocations are growing and growing every time I click a button.
and on my ViewController.h:
IBOutlet UIImageView (...);
IBOutlet UIImageView (...);
IBOutlet UILabel (...);
IBOutlet UIButton (...);
IBOutlet NSTimer (...);
IBOutlet UIImage (...);
IBOutlet UIView (...);
-(IBAction)Back:(id)sender;
#property (nonatomic, assign) int ;
#property (nonatomic) IBOutlet UIButton ;
#property (nonatomic) IBOutlet UIButton ;
#property (nonatomic) IBOutlet UIButton ;
#property (nonatomic) IBOutlet UIView ;
#property (nonatomic) IBOutlet UILabel ;
I tried to give all the details about my code, but if you need anything else just let me know, and thank you all so much!

If Your images are big please see this question: Problem dealloc'ing memory used by UIImageViews with fairly large image in an UIScrollView
To sum up: when using nib files all the assigned images are loaded using
[UIImage imageNamed]
method which is known to cause huge memory allocations because it always caches the images.
Try assigning the images to views in the code with
[UIImage imageWithContentsOfFile:path];
method (it is described in the answer to above question).

In the modal view controller:
[self dismissViewControllerAnimated:TRUE completion:Nil];
In the main View controller check it exists first before presenting it:
iPadViewController *iPadVC;
if (iPadVC == Nil)
iPadVC = [[iPadViewController alloc] initWithNibName:nil bundle:nil];
[self presentViewController:iPadVC animated:YES completion:NULL];
Sounds like iPadVC is always in scope so ARC may not be releasing it.

Related

Assigning image from another class

For some reason the image is not showing with this code:
YellowClass.h
#property (strong, nonatomic) IBOutlet UIImageView *myImage;
BlueClass.m
YellowClass *yellowClass = [[YellowClass alloc] init];
yellowClass.myImage.image = [UIImage imageNamed:#"Img.png"];
Two things. The instance of YellowClass that you create with alloc init is probably not the one you have on screen (though I can't be sure with that small snippet of code). Secondly, the view of yellowClass has not yet been loaded at the time you access its IBOutlet (myImage), so that outlet will be nil.

Adding tag after switching view controllers

I have a randomly generated int that I assign to a tag for a UIImageView on my storyboard in ViewWillAppear.
When I segue to the main menu and try to enter the view again, however, the app crashes. I know it's because of the tag because when I remove it everything works fine.
Any thoughts on why it works the first time but not on times after that? Code below.
ViewController.h:
#interface ViewController : UIViewController{
int tagnumber;
IBOutlet UIImageView *box;
...
}
ViewController.m:
-(void)viewWillAppear:(BOOL)animated{
tagnumber = arc4random()%1000;
box.tag = tagnumber;
...
}
- (IBAction)unwindToThisViewController:(UIStoryboardSegue *)unwindSegue
{
[_animator removeAllBehaviors];
[box removeFromSuperview];
}
MainMenu.m:
-(IBAction)prepareForUnwind:(UIStoryboardSegue *)segue {
}
Basically, when the view disappears and the system is running out of memory, it will call on UIViewController's implementation of didReceiveMemoryWarning. There is a fantastic description of this here: ViewWillDisappear versus dealloc
When you are creating an IBOutput you should really have a weak pointer to it by saying #property (weak, nonatomic) IBOutlet UIImageView *box. Views retain their subviews, and therefore, if a view gets deallocated, its subviews retain count decreases by one. When the view disappears, the system will decide when to deallocate self.view, and when it does, it will automatically release box, and box will get deallocated as well. You don't really need to worry about it.

UIActivityViewController Print Dialog UI Glitches (Bugs?)

I have some strange UI glitches using an UIActivityViewController when on iPad.
Complicated to tell, so here are two videos. One showing the iOS6 behavior and one the faulty iOS7 one:
iOS6: http://quick.as/govpsry7
iOS7: http://quick.as/qr7jtd8b
1st Issue: The arrow is a little bit off it's position on iOS7 (by design?). Common UINavigationBar with UIBarButtonItems.
Code to present the popover (on iPad):
ActivityPopover = [[UIPopoverController alloc] initWithContentViewController:activityViewController];
[activityPopover presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
Nothing fancy here. Sender is the UIBarButtonItem.
2nd Issue: Selecting Print from UIActivityViewController PopOver has some UI transition issues on iOS7. The new Print Options PopOver moves into the view from the left, moving the desaturated background of the whole screen too. Best seen in the 2nd video.
3rd Issue: As seen, when the Print Options dialog is opened the content of the UIWebView adjusts somehow. I don't see a reason for this.
The 1st and 2nd issue even occur when browsing to "about:blank".
Does anybody know something about these glitches? Common bugs?
Edit: The 1st and 2nd look like iOS7 Bugs. I tried SVWebViewController from Sam Vermette and inserted my test code.
In SVWebViewController.m of the Demo insert:
#interface SVWebViewController () <UIWebViewDelegate>
#property (nonatomic, strong) UIBarButtonItem *backBarButtonItem;
#property (nonatomic, strong) UIBarButtonItem *forwardBarButtonItem;
#property (nonatomic, strong) UIBarButtonItem *refreshBarButtonItem;
#property (nonatomic, strong) UIBarButtonItem *stopBarButtonItem;
#property (nonatomic, strong) UIBarButtonItem *actionBarButtonItem;
#property (nonatomic, strong) UIPopoverController *popover; // added
Later in file, at the very bottom, adjust:
- (void)actionButtonClicked:(id)sender {
NSArray *activities = #[[SVWebViewControllerActivitySafari new], [SVWebViewControllerActivityChrome new]];
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:#[self.self.webView.request.URL, self.self.webView.viewPrintFormatter] applicationActivities:activities];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
self.popover = [[UIPopoverController alloc] initWithContentViewController:activityController];
[self.popover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
[self presentViewController:activityController animated:YES completion:nil];
}
}
This produces the same UI glitches when touching the Activity PopOver and Print Icon.
So it is reproducible with a simple demo, too.
Environment: SDK 7.0, current public Xcode (as of 02/25/2014). Targets: iOS6 and iOS7.
Edit 2/3:
Regarding the 3rd Issue I found this, so it's already reported: http://openradar.appspot.com/8668247
Regards,
Frederik
Verified all three Issues to be Apple iOS Bugs.
The 1st and 2nd are visible by Demo mentioned above. The 3rd is even with the Google Browser App visible (on iPad). Source of the 3rd issue is the scaling reset of UIWebView viewPrintFormatter during dialog popup (in fact an internal UIActivity prepareAction).

A few IBOutlets pointing to nil

After a long while I've finally started working with Objective-C again, on my only complete app so far. The goal is to eventually refactor for ARC and possibly storyboards, but for the time being I'm polishing the iOS 4.x target. I am quite rusty, so bar with me if this is a stupid question.
I have a button in my main view that triggers the showAction method. The method is as follows:
- (void)showAbout
{
AboutViewController *aboutView = [[[AboutViewController alloc] init] autorelease];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
aboutView.modalPresentationStyle = UIModalPresentationFormSheet;
}
else
{
aboutView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
}
[self presentModalViewController:aboutView animated:YES];
}
The AboutViewController class has this .h:
#interface AboutViewController : UIViewController <UIActionSheetDelegate, MFMailComposeViewControllerDelegate> {
}
- (IBAction)dismiss:(UIButton *)sender;
- (IBAction)feedback:(UIButton *)sender;
#property (retain) IBOutlet UIButton *dismissButton;
#property (retain) IBOutlet UIButton *feedbackButton;
#property (retain) IBOutlet UIImageView *background;
#property (retain) IBOutlet UITextView *textView;
#end
and everything has been connected properly in the .xib file (the same one for iPhone and iPad). The actions are triggered as expected, and the outlets are accessible, but only on iPhone. When running on iPad, only textView is properly initialized, and all the rest points to nil.
In the .m I have tried this:
#implementation AboutViewController
#synthesize dismissButton = _dismissButton;
#synthesize feedbackButton = _feedbackButton;
#synthesize background = _background;
#synthesize textView = _textView;
// ...
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(#"obj self.dismiss: %#", self.dismissButton);
NSLog(#"frame dismiss: %#", NSStringFromCGRect(self.dismissButton.frame));
}
On iPhone I get this:
2012-02-08 22:51:00.341 myapp[17290:207] obj self.dismiss: <UIButton: 0x70281d0; frame = (180 410; 120 30); opaque = NO; autoresize = LM+W+RM+TM; layer = <CALayer: 0x7028260>>
2012-02-08 22:51:00.342 myapp[17290:207] frame dismiss: {{180, 410}, {120, 30}}
On iPad, instead, I get this:
2012-02-08 22:51:40.428 myapp[17320:207] obj self.dismiss: (null)
2012-02-08 22:51:40.428 myapp[17320:207] frame dismiss: {{0, 0}, {0, 0}}
There is nothing else that happens depending on the UI Idiom, and I'm really confused about this. It's as if on the iPad the outlets for anything other than textView are not set, even though they are correctly linked up in the .xib file. In viewWillAppear, self.textView is working as expected also on iPad. I also tried doing this in viewDidLoad, which should be called before viewWillAppear if I'm not mistaken, and even in the dismiss: method, but they are just never available.
The reason I need to access the buttons' frames is that the about view is relatively complex and fails to reposition its subviews automatically. The only thing I need to do is make the buttons wider on the larger modal view on iPad.
Any hints would be greatly appreciated!
Thanks in advance.
Did you ever have a separate .xibs for iPad and iPhone? If so you might have the same issue I had. That is until #AliSoftware dropped some knowledge on me:
UIView in nib is nil on iPad, and not nil on iPhone
Essentially you need to:
Delete the Build Products Directory
Delete your app from all your simulators
Build and Run
I believe the problem is that a ghost .xib for iPad was hanging around causing issues. Truly wiping the apps clean did the trick. Good luck!

Passing an UIImageView Between Two UIViewController and Loading This UIImageView Into the Last One UIViewController

I have two UIViewControllers, each one with an UIImageView instantiated with IB. Into the first UIViewController you can draw a picture over it UIImageView. I'm copying the first UIImageView from the first UIViewController into the UIImageView of the second one UIViewController before changing the shown UIViewController. Why the UIImageView of the second one UIViewController doesn't show anything?
Thanks for reading.
EDITED.
Into the first one UIViewController I'm copying the first UIImageView like this.
[secondUIViewController.secondUIImageView setImage:self.firstUIImageView.image];
EDITED 2.
A snippet of code is better than a thousand of words. Still not working. Does anyone know why it doesn't work?
// FirstUIViewController.h
#interface FirstUIViewController : UIViewController {
// Maintains the first one UIImageView.
UIImageView *firstUIImageView;
}
#property (nonatomic, retain) UIImageView *firstUIImageView;
#end
// FirstUIViewController.m
// Changes the view between the FirstUIViewController and the SecondUIViewController.
- (void)gotoSecondUIViewController {
// Gains access to the delegate and send a message to switch to a particular view.
AppDelegate *tempDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
SecondUIViewController *tempSecondUIViewController = [[SecondUIViewController alloc]
initWithNibName:#"SecondUIViewController" bundle:nil];
tempSecondUIViewController.secondUIImageView = self.firstUIImageView;
[tempDelegate switchToSecondUIViewController:tempSecondUIViewController animated:YES];
}
// SecondUIViewController.h
#interface SecondUIViewController : UIViewController {
// Maintains the second one UIImageView.
IBOutlet UIImageView *secondUIImageView;
}
#property (nonatomic, retain) IBOutlet UIImageView *secondUIImageView;
#end

Resources