pushViewController memory leak - iphone

I have following code, instrument indicate that the pushViewController method has 32 bytes memory leak on device. Could you please kindly help check what rule I break? Should I change some "retain" to "assign" for declaration? Thanks in advance!
#interface GuideNewsViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
#private
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
UITableView *tableView;
NewsListViewController *newsListViewController;
}
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain, readonly) NSFetchedResultsController *fetchedResultsController;
#property (nonatomic, retain) UITableView *tableView;
#property (nonatomic, retain, readonly) NewsListViewController *newsListViewController;
#implementation GuideNewsViewController
......
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Member *member = [fetchedResultsController objectAtIndexPath:indexPath];
self.newsListViewController.managedObjectContext = self.managedObjectContext;
self.newsListViewController.title = member.memberName;
self.newsListViewController.author = member;
**// leak here**
[self.navigationController pushViewController:self.newsListViewController animated:YES];
}
......
#end
#interface NewsListViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
#private
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
UITableView *tableView;
Member *author;
}
#property (nonatomic, assign) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain) UITableView *tableView;
#property (nonatomic, assign, readonly) NSFetchedResultsController *fetchedResultsController;
#property (nonatomic, assign) Member *author;
#end

Just a guess but, what happen if you change your newsListViewController from retain to assign?
I barely write retain, readonly together.

When does self.newsListViewController be released ? I don't think that point causes problem.
Generally, I pushViewController with following manner.
MySelfViewController *childView = [[MySelfViewController alloc] init];
// set up necessary properties of childView
...
// navigationController will release childView when it pops view controller.
[self pushViewController:childView animated:YES];
// release childView after pushViewController
[childView release];
If childView have to notify self something happened, it can use delegate to notify self.
Edit 1:
An example is as following.
// MySelfViewController.h
#protocol MySelfProtocol <NSObject>
- (void)notifySomethingHappened;
#end
#interface MySelfViewController : UIViewController {
id <MySelfProtocol> _delegate;
}
/// client init childview by pass self as parameter.
/// ex: Inside view controller A, he calls by
/// childView = [[MySelfViewController alloc] initWithDelegate:self];
- (id)initWithDelegate:(id)delegate;
/// other member methods
#end
// MySelfViewController.m
#implement MySelfViewController
- (id)initWithDelegate:(id)delegate
{
if (self = [super init])
{
/// assign policy.
/// childView should not retain parent view or delegate.
/// It is possible to let delegate never run dealloc.
_delegate = delegate;
/// custom initialization
....
}
return self;
}
- (void)someThingHappen
{
[_delegate notifySomethingHappend];
}
#end

Related

Memory leak vs Zombie - iPhone

My iPhone app is either crashing due to to a zombie, or leaking memory.. I've narrowed it down to 3 lines of code and can reliably get one of the two things to happen by commenting/uncommenting the code. The bugs occur when navigation between a list of results (tableView) and a details page containing a map and a few labels, memory leak happens the first time I navigation from the map back to the list of results, the zombie occurs after maybe 5/6 times navigating to different results and back.
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#define METERS_PER_MILE 1609.344
#interface ResDetailsPageVC : UIViewController <MKMapViewDelegate, UIAlertViewDelegate> {
UISegmentedControl *mapTypeSwitcher;
MKMapView *mapView;
UILabel *nameLabel;
UIButton *addressLabel;
UILabel *telephoneLabel;
NSString *address;
}
#property (nonatomic, retain) IBOutlet UISegmentedControl *mapTypeSwitcher;
#property (nonatomic, retain) IBOutlet MKMapView *mapView;
#property (nonatomic, retain) IBOutlet UILabel *nameLabel;
#property (nonatomic, retain) IBOutlet UIButton *addressLabel;
#property (nonatomic, retain) IBOutlet UILabel *telephoneLabel;
- (IBAction)segmentedControlIndexChanged;
- (IBAction)callButtonClick;
- (IBAction)addressClick;
- (void) callNumber;
#end
#synthesize mapView;
#synthesize mapTypeSwitcher;
#synthesize nameLabel, addressLabel, telephoneLabel;
- (void)dealloc {
// if these lines are commented out - memory leak
// if not - zombie?!
/*self.telephoneLabel = nil;
self.addressLabel = nil;
self.nameLabel = nil;*/
self.mapView = nil;
self.mapTypeSwitcher = nil;
[super dealloc];
}
Somewhere some other piece of code is using the same object whose address is stored in one of those three properties, but that other piece of code has not properly retained the object.
I recommend this to you:
- (void)dealloc {
[telephoneLabel release]; telephoneLabel = nil;
[addressLabel release]; addressLabel = nil;
....
[super dealloc];
}

Calling a function in viewcontroller from appdelegate

I want to call a function in a viewController from my appDelegate but with the following code, it doesn't get called. What am I doing wrong?
AppDelegate.h:
#import <UIKit/UIKit.h>
#import "DetailsToTransfer.h"
#class AccountDetailTransferViewController;
#interface AccountDetailTransferAppDelegate : NSObject <UIApplicationDelegate> {
DetailsToTransfer *objDetailsToTransfer;
}
#property (nonatomic, retain) DetailsToTransfer *objDetailsToTransfer;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet AccountDetailTransferViewController *viewController;
-(void)sendToTransferScreen:(NSArray *)detailsArray;
#end
AppDelegate.m:
....
-(void)sendToTransferScreen:(NSArray *)detailsArray {
[objDetailsToTransfer setLabels:detailsArray];
objDetailsToTransfer = [[DetailsToTransfer alloc]initWithNibName:#"DetailsToTransfer" bundle:nil];
[self.window addSubview:objDetailsToTransfer.view];
}
DetailsToTransfer.h:
#import <UIKit/UIKit.h>
#interface DetailsToTransfer : UIViewController {
NSArray *accountDetailsArray;
UILabel *nameLabel;
UILabel *accountLabel;
IBOutlet UIButton *btnTransfer;
IBOutlet UIButton *btnBack;
}
#property (nonatomic, retain) NSArray *accountDetailsArray;
#property (nonatomic, retain) IBOutlet UILabel *nameLabel;
#property (nonatomic, retain) IBOutlet UILabel *accountLabel;
-(IBAction)sendDetails;
-(IBAction)goBack;
-(void)setLabels:(NSArray *)array;
#end
DetailsToTransfer.m
....
-(void)setLabels:(NSArray *)array {
NSLog(#"Setting Labels");
self.nameLabel.text = [array objectAtIndex:0];
self.accountLabel.text = [array objectAtIndex:1];
}
....
I would like to add that all the properties have been synthesized and that I'm calling the method in the appDelegate properly (i checked using NSLogs)
In AppDelegate.m:
Looks as if you are calling a method on your object before the object has been created. Until you have alloc / init your object, there will be no labels to set text.
Try changing your method to this:
-(void)sendToTransferScreen:(NSArray *)detailsArray {
if (!objDetailsToTransfer) {
objDetailsToTransfer = [[DetailsToTransfer alloc]initWithNibName:#"DetailsToTransfer" bundle:nil];
[objDetailsToTransfer setLabels:detailsArray];
[self.window addSubview:objDetailsToTransfer.view];
}
}
The problem might be that you are trying to set the values on a object that hasn't been created yet. I also provided an if statement to prevent the object from being created multiple times.

Cant set row selected for RSS app in iphone

OK, i'm making an app that pulls down rss feeds, the initial table view is the headlines, the second view shows the detail of that headline the user selected.
This is the code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[[self appDelegate] setCurrentlySelectedBlogItem:[[[self rssParser]rssItems]objectAtIndex:indexPath.row]];
NewsDetailViewController *newsDetail = [[NewsDetailViewController alloc] initWithNibName:#"NewsDetailViewController" bundle:nil];
//NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
// ...
// Pass the selected object to the new view controller.
newsDetail.titleTextView.text = [[[self appDelegate] currentlySelectedBlogItem]title];
newsDetail.descriptionTextView.text = [[[self appDelegate] currentlySelectedBlogItem]description];
[self.navigationController pushViewController:newsDetail animated:YES];
[newsDetail release];
}
setCurrentlySelectedBlogItem is a pointer to blogrss class which is reference in the AppDelegate. When i'm clicking on the row of the headline and its taking me to the next view, the content is empty. In the last two lines above i'm attempting to set the UILabel's as the current headline's details...
Anyone hazard a guess to why this is happening?
Also this is my AppDelegate.h file:
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#class RssFunViewController;
#class NewsDetailViewController;
#class RootViewController;
#class BlogRss;
#class BlogRssParser;
#interface ExampleAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navigationController;
RootViewController *viewController;
NewsDetailViewController * newsDetailController;
BlogRss * currentlySelectedBlogItem;
#private
NSManagedObjectContext *managedObjectContext_;
NSManagedObjectModel *managedObjectModel_;
NSPersistentStoreCoordinator *persistentStoreCoordinator_;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet RootViewController *viewController;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#property (nonatomic, retain) IBOutlet NewsDetailViewController * newsDetailController;
#property (readwrite,retain) BlogRss * currentlySelectedBlogItem;
#property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
#property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (NSString *)applicationDocumentsDirectory;
- (void)saveContext;
#end
The UILabels in the view controller are probably still nil at that point and not accessible. Instead of setting the controls directly, create two NSString properties in the NewsDetailViewController and set those before you push it. Then, in the NewsDetailViewController, set the labels to the property values in the viewDidLoad method (at which point the labels should be instantiated and accessible).

Class Delegate does not implement protocol

I`m doing something wrong here but I can't figure out what it is .
AppDelegate.h
#import <UIKit/UIKit.h>
#interface AppDelegate : NSObject <UIApplicationDelegate, UIScrollViewDelegate> {
UIWindow *window;
UIScrollView *scrollView;
UIPageControl *pageControl;
NSMutableArray *viewControllers;
UIView *flipside;
// To be used when scrolls originate from the UIPageControl
BOOL pageControlUsed;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
#property (nonatomic, retain) IBOutlet UIPageControl *pageControl;
#property (nonatomic, retain) IBOutlet UIView *flipside;
#property (nonatomic, retain) NSMutableArray *viewControllers;
- (IBAction)showInfo:(id)sender;
- (IBAction)changePage:(id)sender;
#end
AppDelegate.m
- (IBAction)showInfo:(id)sender {
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
This is where I`m getting :
warning: class 'AppDelegate' does not implement the 'FlipsideViewControllerDelegate' protocol.
After line :
controller.delegate = self;
My FlipsideViewController.h looks like this :
#import <UIKit/UIKit.h>
#protocol FlipsideViewControllerDelegate;
#interface FlipsideViewController : UIViewController {
id <FlipsideViewControllerDelegate> delegate;
}
#property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
- (IBAction)done:(id)sender;
#end
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
#en
Any help would be greatly appreciated :)
It's exactly what the error message says. AppDelegate just doesn't implement the protocol. In your header file, add FlipsideViewControllerDelegate between the brackets (i.e. <UIApplicationDelegate, UIScrollViewDelegate, FlipsideViewControllerDelegate>), and implement the -flipsideViewControllerDidFinish: method.
try adding FlipsideViewControllerDelegate to the appDelegate
#interface AppDelegate : NSObject <UIApplicationDelegate, UIScrollViewDelegate,FlipsideViewControllerDelegate> {
UIWindow *window;
UIScrollView *scrollView;
UIPageControl *pageControl;
NSMutableArray *viewControllers;
UIView *flipside;
// To be used when scrolls originate from the UIPageControl
BOOL pageControlUsed;
}

How to resolve warning about does not implement the 'UIActionSheetDelegate' protocol

here is my .h code
#interface ROSettingViewController : UITableViewController
{
UISwitch *switchCtl;
UISwitch *switchCtl1;
NSArray *dataSourceArray;
}
#property (nonatomic, retain, readonly) UISwitch *switchCtl;
#property (nonatomic, retain, readonly) UISwitch *switchCtl1;
#property (nonatomic, retain) NSArray *dataSourceArray;
- (void)dialogOKCancelAction;
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex;
#end
/Users/ragopor/Desktop/Power Spot beta 2/code/Classes/ROSettingViewController.m:321: warning: class 'ROSettingViewController' does not implement the 'UIActionSheetDelegate' protocol
Have you tried declaring your controller's adherence to the UIActionSheetDelegate protocol?
#interface ROSettingViewController : UITableViewController<UIActionSheetDelegate>
The chances are you're saying, on ROSettingViewController.m:321,
myActionSheet.delegate = self;
without having specified that your VC implements the UIActionSheetDelegate protocol