iPhone delegate & controller dealloc? - objective-c

I have been playing with a simple iphone app and decided to put an NSLog statement in the deallocs of both the controller and the delegate but neither of these print out to the Xcode console?
// APPLICATION DELEGATE
#import "iPhone_buttonFunAppDelegate.h"
#import "iPhone_buttonFunViewController.h"
#implementation iPhone_buttonFunAppDelegate
#synthesize window;
#synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
NSLog(#"applicationDidFinishLaunching ...");
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
- (void)applicationWillTerminate:(UIApplication *)application {
NSLog(#"AWT:");
}
- (void)dealloc {
NSLog(#"-DEL-"); // << Does not print?
[viewController release];
[window release];
[super dealloc];
}
#end
// VIEW CONTROLLER
#import "iPhone_buttonFunViewController.h"
#implementation iPhone_buttonFunViewController
#synthesize statusText;
-(IBAction)buttonPressed:(id) sender {
NSString *title;
NSString *newText;
title = [sender titleForState:UIControlStateNormal];
newText = [[NSString alloc] initWithFormat:#"%# button pressed.", title];
[statusText setText:newText];
[newText release];
NSLog(#"Button Press ... %#", title);
}
-(void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
NSLog(#"-1-");
}
-(void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
NSLog(#"-2-");
self.statusText = nil;
}
-(void)dealloc {
NSLog(#"-CON-"); // << Does not print?
[statusText release];
[super dealloc];
}
#end
gary

This is an optimization in the Cocoa touch runtime. Certain deallocations aren't made at the end of the program, since the entire program is going to exit and they will be wiped out anyway.

This problem with NSLog(...) may be answered by this other stackoverflow question about applicationWillTerminate:
Good luck.

Related

Can't override a simple method

I've created a new project with two ViewControllers and imported a class that pushes ViewController from right to left instead LTR but can't manage to use it. I can see that pushViewController inside UIRightToLeft.m is not being called and I don't understand why.
My main goal is to get that working with RTL aniamtion.
#import "UIRightToLeft.h"
#implementation UIRightToLeft
- (id)initWithRootViewController:(UIViewController *)rootViewController
{
self = [super initWithRootViewController:rootViewController];
if (!self)
return nil;
return self;
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSLog(#"pushViewController");
// Add the viewController and a fake controller without animation. Then pop the fake controller with animation.
UIViewController *fakeController = [[UIViewController alloc] init] ;
[super setViewControllers:[[self viewControllers] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:viewController, fakeController, nil]] animated:NO];
[super popViewControllerAnimated:animated];
}
- (void)popViewControllerAnimatedStep2:(UIViewController *)viewController
{
// Push the new top controller with animation
[super pushViewController:viewController animated:YES];
// Remove the view that should have been popped
NSMutableArray *arr = [NSMutableArray arrayWithArray:[self viewControllers]];
[arr removeObjectAtIndex:[[self viewControllers] count]-2];
[super setViewControllers:[NSArray arrayWithArray:arr] animated:NO];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
NSLog(#"popViewControllerAnimated");
if (animated)
{
// Save the controller that should be on top after this pop operation
UIViewController *newTopController = [[self viewControllers] objectAtIndex:[[self viewControllers] count]-2];
// Remove it from the stack. Leave the view that should be popped on top
NSMutableArray *arr = [NSMutableArray arrayWithArray:[self viewControllers]];
[arr removeObjectAtIndex:[[self viewControllers] count]-2];
[super setViewControllers:[NSArray arrayWithArray:arr] animated:NO];
// Schedule the next step
[self performSelector:#selector(popViewControllerAnimatedStep2:) withObject:newTopController afterDelay:0];
return [arr objectAtIndex:[arr count]-1];
}
return [super popViewControllerAnimated:NO];
}
#end
ViewController.m:
#import "ViewController.h"
#import "UIRightToLeft.h"
#import "SecondViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)pressMe:(UIButton *)sender {
SecondViewController *next = [[SecondViewController alloc]init];
[self.navigationController pushViewController:next animated:YES];
}
#end
ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
- (IBAction)pressMe:(UIButton *)sender;
#end
(In my ViewController there's only one button draged to the second ViewController with push)
After looking at your error log I think you actually need to have your navigation controller subclass UIRightToLeft.
If you are using a Storyboard, select your navigation controller and set Custom Class to UIRightToLeft.

iOS: Memory leak in simple MVC model

I've build (must be simple...) MVC model, but I still have memory leak when pushing back button.
Model class: .h
#interface Nominal : NSObject {
int nominalID;
NSString *nominal;
NSString *nominalImg;
NSString *nominalName;
}
#property(nonatomic)int nominalID;
#property(nonatomic,retain)NSString *nominal;
#property(nonatomic,retain)NSString *nominalImg;
#property(nonatomic,retain)NSString *nominalName;
#end
.m
#implementation Nominal
#synthesize nominal,nominalID,nominalImg,nominalName;
-(void)dealloc
{
[self.nominal release];
[self.nominalImg release];
[self.nominalName release];
}
#end
I do release the strings as well.
In my view class I populate it so:
.h
#interface Nominals : UIViewController {
...
NSMutableArray *nominalsArr;
...
}
#property(retain,nonatomic)NSMutableArray *nominalsArr;
.m
- (void)viewWillAppear:(BOOL)animated
{
[[self navigationController]setToolbarHidden:YES animated:YES];
DBAccess *dbAccsess=[[DBAccess alloc]init];
self.nominalsArr=[dbAccsess returnNominals:subCountryID];
[dbAccsess closeDataBase];
[dbAccsess release];
[super viewWillAppear:animated];
}
- (void)dealloc
{
[nominalsArr release];
[self.navigationController release];
[super dealloc];
}
Looks like I do release the whole bundle of holy things, but when I push pack button from this view to previous, the memory leak pops up:
What I'm doing wrong?
You help is utterly appreciated.
You've forgotten a [super dealloc] in [Nominal -dealloc]. Also, don't call [self.navigationController release] as that property is already handled by the superclass (UIViewController).

NSWindowController not hiding its window at init?

I have an NSDocument subclass with two NSWindowControllers corresponding to 2 different xib.
Following the Document-Based Application Guide I have added the following in my document.m implementation
- (void)makeWindowControllers
{
NSLog(#"in MakeWindowControllers");
MainWindowController *mainWindowController = [[MainWindowController alloc] init];
[mainWindowController autorelease];
[self addWindowController:mainWindowController];
csvWindowController = [[CSVWindowController alloc] init];
[csvWindowController autorelease];
[self addWindowController:csvWindowController];
}
Problem is I want the second window controller csvWindowController to hide its window initially, I will show the same instance of the window later on. To do so I have written:
#implementation CSVWindowController
- (id) init {
if ( ! (self = [super initWithWindowNibName:#"CSVWindow"]) ) {
NSLog(#"CSVWindowController init failed");
return nil;
}
window = [self window];
NSLog(#"CSVWindowController init");
[window orderOut:nil]; // to hide it
NSLog(#"CSVWindowController hiding the window");
return self;
}
But the window is there, showing up.
Please not I have the VisibleAtLaunch not flagged, that console it's showing my messages correctly, and that even if I change:
[window orderOut:nil]; // to hide it
to
[window orderOut:self]; // to hide it
The result is the same, window showing up.
Any help is appreciated, thanks :)
Ok, again I reply to my own question, but this time with a positive remark. I think what I was doing wrong had something to do with the hidden - for me - implications of the Document-based architecture of the default Document Application template.
I have tried with a different approach, creating an application from scratch NOT flagging "Document-based Application" and providing it with:
1 NSDocument subclass
2 NSWindowControllers subclasses
1 MainMenu.xib
2 window.xib
and I have forced instantiation of the NSWindowController subclasses in the MyDocument code.
I have also put the IBActions for the MenuItems in the MyDocument and I have bound the MyDocument Object to the MenuItems in the MainMenu.xib.
This time I was able to do whatever, hiding/showing windows starting with one hidden one not, enabling menu items automatically at will.
Here follows the code, for any newbie like me who might have to fight with this in the future.
// MyDocument.h
#import <Cocoa/Cocoa.h>
#import "testWindowController.h"
#import "test2WindowController.h"
#interface MyDocument : NSDocument {
testWindowController *test;
test2WindowController *test2;
}
- (IBAction)showWindow1:(id)pId;
- (IBAction)showWindow2:(id)pId;
- (IBAction)hideWindow1:(id)pId;
- (IBAction)hideWindow2:(id)pId;
#end
// MyDocument.m
#import "MyDocument.h"
#import "testWindowController.h"
#import "test2WindowController.h"
#implementation MyDocument
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
NSLog(#"MyDocument init...");
[self makeWindowControllers];
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)makeWindowControllers
{
test = [[testWindowController alloc] init];
test2 = [[test2WindowController alloc] init];
[self addWindowController:test];
[self addWindowController:test2];
// start hiding the first window
[[test window] orderOut:self];
}
- (IBAction)hideWindow1:(id)pId
{
NSLog(#"hideWindow1");
[[test window] orderOut:self];
}
- (IBAction)showWindow1:(id)pId
{
NSLog(#"showWindow1");
[test showWindow:self];
[[test window] makeKeyAndOrderFront:nil]; // to show it
}
- (IBAction)hideWindow2:(id)pId
{
NSLog(#"hideWindow2");
[[test2 window] orderOut:self];
}
- (IBAction)showWindow2:(id)pId
{
NSLog(#"showWindow2");
[test2 showWindow:self];
[[test2 window] makeKeyAndOrderFront:nil]; // to show it
}
-(BOOL)validateMenuItem:(NSMenuItem *)menuItem {
NSLog(#"in validateMenuItem for item: %#", [menuItem title]);
if ([[menuItem title] isEqualToString:#"Show Window"]
&& [[test window] isVisible]){
return NO;
}
if ([[menuItem title] isEqualToString:#"Hide Window"]
&& ![[test window] isVisible]){
return NO;
}
if ([[menuItem title] isEqualToString:#"Show Window2"]
&& [[test2 window] isVisible]){
return NO;
}
if ([[menuItem title] isEqualToString:#"Hide Window2"]
&& ![[test2 window] isVisible]){
return NO;
}
return [super validateMenuItem:menuItem];
}
This is another method to prevent NSDocument's window(s) to show up early:
Subclass NSDocuments's window in IB
Use a flag to signal when window content is ready
Override makeKeyAndOrderFront method.
#interface DocWindow : NSWindow
#property BOOL inited;
#end
#implementation DocWindow
- (void)makeKeyAndOrderFront:(id)sender
{
if ( _inited )
[super makeKeyAndOrderFront:sender];
}
#end
#implementation Document
- (void)windowControllerDidLoadNib:(NSWindowController *)windowController
{
// prepare window content here.
...
// show doc's window when ready
DocWindow *win = (DocWindow *)self.window;
win.inited = YES;
[win makeKeyAndOrderFront:self];
}
#end

How to Change view(XIB) after imagePickerController:didFinishPickingMediaWithInfo?

I am new on iphone and objective-c development.
I want to know how i can change the view (XIB File) after the camera takes a picture.
Can anyone help me or share some code? I am searching for this since a week :(
After finishing the app, i am ready to share my project and/or make a tutorial.
Infos about my App: i want to scan barcodes and save the barcodes in my app.
For scanning barcodes iam using the ZBarSDK.
I hava a TabBarController, on the first Tab, i can open the camera.
After the scan process i want to jump to the second tab (another XIB File) and show the results.
Thanks for any help.
Here my code of the first tab (ScanCodeViewController):
.h
#import < UIKit/UIKit.h >
#class OutPutCodeViewController;
#interface ScanCodeViewController : UIViewController <ZBarReaderDelegate> {
IBOutlet UIImageView *img;
OutPutCodeViewController *output;
}
#property (nonatomic, retain) IBOutlet UIImageView *img;
#property (nonatomic, retain) OutPutCodeViewController *output;
- (IBAction) scanButton;
#end
.m
#import "ScanCodeViewController.h"
#implementation ScanCodeViewController
#synthesize img;
#synthesize output;
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[img release];
[super dealloc];
}
- (IBAction) scanButton {
NSLog(#"Scanbutton wurde geklickt!");
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
ZBarImageScanner *scanner = reader.scanner;
[scanner setSymbology: ZBAR_I25 config: ZBAR_CFG_ENABLE to: 0];
[self presentModalViewController:reader animated: YES];
[reader release];
}
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
NSLog(#"Entered imagePickerController");
// ADD: get the decode results
id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results) {
break;
}
img.image = [info objectForKey:UIImagePickerControllerOriginalImage];
[reader dismissModalViewControllerAnimated: YES];
//[self presentModalViewController:output animated:YES]; //by using this, app chrashes
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissModalViewControllerAnimated: YES];
}
#end
And here the Secong Tab (OutPutCodeViewController)
.h
#import <UIKit/UIKit.h>
#interface OutPutCodeViewController : UIViewController {
IBOutlet UIImageView *resultImage;
IBOutlet UITextField *resultText;
}
#property (nonatomic, retain) IBOutlet UIImageView *resultImage;
#property (nonatomic, retain) IBOutlet UITextField *resultText;
#end
.m
#import "OutPutCodeViewController.h"
#implementation OutPutCodeViewController
#synthesize resultImage;
#synthesize resultText;
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[resultImage release];
[resultText release];
[super dealloc];
}
#end
Got it!
It is not possible to set more animate:YES.
Here is the sample and right code.
I hope it helps others.
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
break;
[reader dismissModalViewControllerAnimated: NO];
TableDetailViewController *tc = [[TableDetailViewController alloc] initWithNibName:#"TableDetailViewController" bundle:nil];
tc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:tc animated:YES];
[tc release];
}
brush51
In didFinishPickingMediaWithInfo you should call [self.tabBarController setSelectedIndex:1] to switch to the second tab.

Loading presentModalViewController in ViewDidAppear causes EXC_BAD_ACCESS

In the Follwoing ViewControllerClass I get EXC_BAD_ACCESS when trying to call presentModalViewController in ViewDidAppear method.
#import "SounderViewController.h"
#import "ASIFormDataRequest.h"
#import "ASIHTTPRequest.h"
#import "JSON.h"
#import "InfoViewController.h"
#implementation SounderViewController
#synthesize ipod;
#synthesize ivc;
#synthesize title_lb, artist_lb, check;
-(IBAction)showCurrentSongInfo{
MPMediaItem * song = [ipod nowPlayingItem];
NSString * title = [song valueForProperty:MPMediaItemPropertyTitle];
NSString * artist = [song valueForProperty:MPMediaItemPropertyArtist];
title_lb.text = title;
artist_lb.text = artist;
}
-(void)playbackStateChanged: (NSNotification*) notification{
[self showCurrentSongInfo];
NSLog(#"Playback state: %#",[notification name]);
if (ipod.playbackState != MPMusicPlaybackStatePlaying) {
NSLog(#"Is not playing");
[self presentModalViewController:self.ivc animated:YES];
}else if (ipod.playbackState == MPMusicPlaybackStatePlaying) {
NSLog(#"Is playing");
[self dismissModalViewControllerAnimated:YES];
}
}
-(void)nowPlayingItemChanged: (NSNotification*) notification{
[self showCurrentSongInfo];
NSLog(#"Playing item changed: %#",[notification name]);
}
- (void)viewDidLoad {
[super viewDidLoad];
self.ivc = [[InfoViewController alloc] initWithNibName:#"InfoViewController" bundle:nil];
self.ipod = [MPMusicPlayerController iPodMusicPlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector (playbackStateChanged:)
name:#"MPMusicPlayerControllerPlaybackStateDidChangeNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector (nowPlayingItemChanged:)
name:#"MPMusicPlayerControllerNowPlayingItemDidChangeNotification"
object:nil];
[[MPMusicPlayerController iPodMusicPlayer] beginGeneratingPlaybackNotifications];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
if (ipod.playbackState != MPMusicPlaybackStatePlaying) {
[self presentModalViewController:self.ivc animated:YES];
}else{
[self showCurrentSongInfo];
}
}
-(IBAction)showInfoView{
[self presentModalViewController:self.ivc animated:YES];
}
#pragma mark View Methods
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
Method call
[self presentModalViewController:self.ivc animated:YES];
in ViewDidAppear causes EXC_BAD_ACCESS.
I have tried debuging it with NSZombieEnabled but got only a stack call to main.
The thing that gets me crazy is that if the same code is run from method playbackStateChanged it works fine.
If any of you can help I wan't get bold as quick. Thanks.
I finally made it to work! But I think it's just quick fix.
So I found out that to make my ivc to show up I need to delay the call to presentModalViewController
[self performSelector:#selector(showWaitingMessageView:) withObject:self.ivc afterDelay:1];
That's it. It works.
I don't know why this helped, so if one of you gurus knows more about it please enlighten me.