NSMutableArray not pass value to CellForRowAtIndexPath? - iphone

I can put value into array and here is my code and prob.
Search.h
#interface SearchKeyword : UIViewController {
UITableView * newsTable;
UILabel * waitLabel;
UIActivityIndicatorView *activityIndicator;
UIView * backView;
NSMutableArray *jsonKanji;
}
#property (nonatomic, retain) IBOutlet UITableView * newsTable;
#property (nonatomic, retain) IBOutlet UILabel * waitLabel;
#property (nonatomic, retain) IBOutlet UIActivityIndicatorView * activityIndicator;
#property (nonatomic, retain) IBOutlet UIView * backView;
- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier;
#end
and here is Search.m
- (void)viewDidAppear:(BOOL)animated{
...
jsonKanji = [NSMutableArray arrayWithArray:(NSArray *)[jsonDict valueForKey:#"kanji_name"]];
...
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"jsonkanji 0 %#",[jsonKanji objectAtIndex:0]);
return [jsonKanji count];
}
Here is result "jsonkanji 0 Japan" that correct and If I change objAtindex=1 It show "jsonkanji 1 England" that's correct too.
But when I go to this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"jsonkanji 0 %#",[jsonKanji objectAtIndex:1]);
...
return cell;
}
It's crash !! plase help me explain what happen ? And it show only "EXC_BAD_ACCESS" #main.m

You have a memory management issue. [NSMutableArray arrayWithArray:] gives you an autoreleased object, as per Apple's memory management guidelines.
In your first test, you're checking the value at some point before the object is dealloc'd. By the time the delegate call from the table view has arrived the object has been dealloc'd, and the memory no longer exists.
You need to make sure to retain the array when you create it (and release it when you are finished with it).
You can do this explicitly:
- (void)viewDidAppear:(BOOL)animated{
...
jsonKanji = [[NSMutableArray arrayWithArray:(NSArray *)[jsonDict valueForKey:#"kanji_name"]] retain];
...
}
Or create a property and assign the value using the property, which will handle the retain itself:
(interface)
#interface SearchKeyword : UIViewController {
....
#property (nonatomic, retain) INSMutableArray *jsonKanji;
...
#end
(implementation)
- (void)viewDidAppear:(BOOL)animated{
...
self.jsonKanji = [NSMutableArray arrayWithArray:(NSArray *)[jsonDict valueForKey:#"kanji_name"]];
...
}

NSMutableArray arrayWithArray: is autoreleased. You need to retain it.

You need to retain the NSMutable array, try creating a property for the array.
Add the following to your .h file
#property (nonatomic, retain) NSMutableArray *jsonKanji;
Then #synthesize the jsonKanji in the .m file.
And change the loading of the array to:
- (void)viewDidAppear:(BOOL)animated{
...
self.jsonKanji = [NSMutableArray arrayWithArray:(NSArray *)[jsonDict valueForKey:#"kanji_name"]];
...
}

Related

Writing to a label when creating a custom cell Xcode

I keep running into a problem when I try to write to a label in a custom cell. So right now, I have a class with a table view called "AccountViewController" and I have a class with my custom cell "AccountViewCell. I can get my cell to correctly display in my table, however I run into a problem when I try to link the label in my custom cell to their outlets and when I write to the labels.
Right now my code is:
AccountViewController.h
#import <UIKit/UIKit.h>
#import <GameKit/GKSession.h>
#import <GameKit/GKPeerPickerController.h>
#interface AccountViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
NSArray *tableData;
int cellValue;
NSString *cellContents;
}
#property (nonatomic, retain) NSArray *tableData;
#property (nonatomic, retain) NSString *cellContents;
#property (nonatomic, retain) NSString *accountSelected;
#property (nonatomic, retain) NSString *accountList;
#property (nonatomic, retain) NSString *amount;
#end
AccountViewController.m
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"AccountViewCell";
AccountViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"AccountViewCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
cell = [topLevelObjects objectAtIndex:0];
}
// cell.accountNameLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
AccountViewCell.h:
#import <UIKit/UIKit.h>
#interface AccountViewCell : UITableViewCell
#property (nonatomic, weak) IBOutlet UILabel *accountNameLabel;
#property (nonatomic, weak) IBOutlet UILabel *accountNumberLabel;
#property (nonatomic, weak) IBOutlet UILabel *balanceLabel;
#end
AccountViewCell.m
#import "AccountViewCell.h"
#implementation AccountViewCell
#synthesize accountNameLabel = _accountNameLabel;
#synthesize accountNumberLabel = _accountNumberLabel;
#synthesize balanceLabel = _balanceLabel;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
Again, my code works fine and displays my custom cell when I don't try to set a label's text or connect the outlets to the labels in AccountViewCell as shown here:
http://i.imgur.com/TuFun5y.png
My cell Identifier is correct: http://i.imgur.com/ZbsDvaa.png
Now, the problem is when I connect the outlets like this: http://imgur.com/OOiKpkM
The code will break, even if I don't set or declare the labels in AccountViewController.m It gives me this error:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AccountViewController 0x104b2220> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key accountNameLabel.'
*** First throw call stack:
(0x248e012 0x1d2be7e 0x2516fb1 0x815711 0x796ec8 0x7969b7 0x7c1428 0xd620cc 0x1d3f663 0x248945a 0xd60bcf 0xd6298d 0x28e54 0xbfff4b 0xc0001f 0xbe880b 0xbf919b 0xb9592d 0x1d3f6b0 0x287ffc0 0x287433c 0x2874150 0x27f20bc 0x27f3227 0x27f38e2 0x2456afe 0x2456a3d 0x24347c2 0x2433f44 0x2433e1b 0x29e37e3 0x29e3668 0xb4565c 0x49b2 0x2c45)
libc++abi.dylib: terminate called throwing an exception
I need a way to be able to write to the label. I've tried everything I could think of and read many threads, however I cannot figure this out. If someone could please help and could show me a way to write to a label in a custom cell, that would be great.
Ok, I figured it out. I should not have been linking the labels via file owner but instead via the table cell.

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];
}

Change text in UILabel with NSMutablearray data

I'm trying to change the text of a UILabel with text from an array upon a button click, but it doesn't do anything.
#interface Test01AppDelegate : NSObject <UIApplicationDelegate> {
UILabel *helloLabel;
UIButton *hellobutton;
NSMutableArray *madWords;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UIButton *hellowButton;
#property (nonatomic, retain) IBOutlet UILabel *hellowLabel;
#property (nonatomic, retain) NSMutableArray *madWords;
- (void) madArrays;
- (IBAction)helloYall;
#end
and
#import "Test01AppDelegate.h"
#implementation Test01AppDelegate
#synthesize window = _window;
#synthesize hellowButton;
#synthesize hellowLabel;
#synthesize madWords;
- (void) madArrays {
[madWords addObject:#"Part A"];
[madWords addObject:#"Part B"];
[madWords addObject:#"Part C"];
[madWords addObject:#"Part D"];
}
- (IBAction)helloYall {
[self madArrays];
self.hellowLabel.text = [madWords objectAtIndex:0];
}
I can set the helloLabel text with
#"some text here";
and it works fine. Also, I tried copying the "madArrays" method into the "helloYall" method and it still didn't work. As I said, I can manually set the text and it works, but I'd like to pull the info from an array. Eventually, I'd like to loop through the array to grab the text on each button press, but one step at a time. Thanks.
You never create the madWords array. You need to add:
self.madWords = [NSMutableArray array];
at the top of:
- (void) madArrays {
would probably be a good place. Other possibly good places would be i the class init method or the view controller viewWillAppear method.
// Or you can try this in your init Method:
//first allocate the ivar
- (void)myInitMethod {
madArrays = [[NSMutableArray]alloc]init];
}
//then you can do anything directly to the ivar or throughout de setter
- (void)doAnythingWithiVar {
// do your stuff
}
//when you are done you can dealloc your ivar
- (void)dealloc {
[madArrays release];
[super dealloc];
}
It looks like madArrays is still nil when you come to populate it. At some point you need something like [self setMadArrays:[[NSMutableArray alloc] init]];. Also, don't forget to release madArrays in the dealloc before calling super as you'll have a memory leak.

How to sum contents of reusable Custom Cells for a Table View that acts as a Calculator

I built a table view, with Custom Table View Cells, where each cell has several UITextFields that allow the user to enter numbers that provide a calculation. The cell hast a subtotal UITextField that provides the result for that cell.
My problem is that I want to take the subtotal of that cell, and of each additional cell that the User uses, and provide a Total on a different UIView.
I do not know how to take the value of each subtotal for each cell, and furthermore, how can I know how many cells the user used, and all of this in order to provide the user with a TOTAL in a different view.
What would be the best way to achieve this?
Here is the Code.
I want to add new cells and be able to add them to the calculation. But each cell will hold different values that the user will provide.
Best!
#import <UIKit/UIKit.h>
#interface ProCalculator : UIViewController <UITableViewDelegate, UITableViewDataSource> {
UITextField *totalField;
UITextField *differenceField;
UITextField *productField;
UITextField *price1Field;
UITextField *discount1P1Field;
UITextField *discount2P1Field;
UITextField *subtotal1Field;
UITextField *product2Field;
UITextField *price2Field;
UITextField *discount1P2Field;
UITextField *discount2P2Field;
UITextField *subtotal2Field;
}
#property (nonatomic, retain) IBOutlet UITextField *totalField;
#property (nonatomic, retain) IBOutlet UITextField *differenceField;
#property (nonatomic, retain) IBOutlet UITextField *productField;
#property (nonatomic, retain) IBOutlet UITextField *price1Field;
#property (nonatomic, retain) IBOutlet UITextField *discount1P1Field;
#property (nonatomic, retain) IBOutlet UITextField *discount2P1Field;
#property (nonatomic, retain) IBOutlet UITextField *subtotal1Field;
#property (nonatomic, retain) IBOutlet UITextField *product2Field;
#property (nonatomic, retain) IBOutlet UITextField *price2Field;
#property (nonatomic, retain) IBOutlet UITextField *discount1P2Field;
#property (nonatomic, retain) IBOutlet UITextField *discount2P2Field;
#property (nonatomic, retain) IBOutlet UITextField *subtotal2Field;
-(IBAction)calculateDiscounts:(id)sender;
-(IBAction)removeKeyboard;
#end
#import "ProCalculator.h"
#import "ProductCell.h"
#implementation ProCalculator
#synthesize totalField, differenceField, productField, price1Field, discount1P1Field, discount2P1Field, subtotal1Field;
#synthesize product2Field, price2Field, discount1P2Field, discount2P2Field, subtotal2Field;
-(IBAction)calculateDiscounts:(id)sender
{
//Calculate product 1 within first Cell
NSString *firstPrice = self.price1Field.text;
NSString *discount1P1 = self.discount1P1Field.text;
NSString *discount2P1 = self.discount2P1Field.text;
double subtotal1WithDiscount1;
double subtotal1WithDiscount2;
double firstPriceDouble = [firstPrice doubleValue];
double discount1P1Double = [discount1P1 doubleValue];
double discount2P1Double = [discount2P1 doubleValue];
double percentageDiscount1P1;
double percentageDiscount2P1;
double savings1P1;
double savings2P1;
percentageDiscount1P1 = discount1P1Double / 100;
percentageDiscount2P1 = discount2P1Double / 100;
savings1P1 = firstPriceDouble * percentageDiscount1P1;
subtotal1WithDiscount1 = firstPriceDouble - savings1P1;
savings2P1 = subtotal1WithDiscount1 * percentageDiscount2P1;
subtotal1WithDiscount2 = subtotal1WithDiscount1 - savings2P1;
NSString *finalSubtotal1 = [[NSString alloc] initWithFormat:#"$ %.02f", subtotal1WithDiscount2];
self.subtotal1Field.text = finalSubtotal1;
//Calculate product 2 within second Cell (Instead of Building more cells, I need to get information from User Input to create Cells and store information from them and add them to the calculation.
NSString *secondPrice = self.price1Field.text;
NSString *discount1P2 = self.discount1P2Field.text;
NSString *discount2P2 = self.discount2P2Field.text;
double subtotal2WithDiscount1;
double subtotal2WithDiscount2;
double secondPriceDouble = [secondPrice doubleValue];
double discount1P2Double = [discount1P2 doubleValue];
double discount2P2Double = [discount2P2 doubleValue];
double percentageDiscount1P2;
double percentageDiscount2P2;
double savings1P2;
double savings2P2;
percentageDiscount1P2 = discount1P2Double / 100;
percentageDiscount2P2 = discount2P2Double / 100;
savings1P2 = secondPriceDouble * percentageDiscount1P2;
subtotal2WithDiscount1 = secondPriceDouble - savings1P2;
savings2P2 = subtotal2WithDiscount1 * percentageDiscount2P2;
subtotal2WithDiscount2 = subtotal2WithDiscount1 - savings2P2;
NSString *finalSubtotal2 = [[NSString alloc] initWithFormat:#"$ %.02f", subtotal2WithDiscount2];
self.subtotal1Field.text = finalSubtotal2;
//Calculate Total
double totalAmount;
totalAmount = subtotal1WithDiscount2 + subtotal2WithDiscount2;
NSString *theTotal = [[NSString alloc] initWithFormat:#"$ %.02f", totalAmount];
self.totalField.text = theTotal;
//Calculate Money Saved
double moneySaved;
moneySaved = savings1P1 + savings2P1 + savings1P2 + savings2P2;
NSString *theMoneySaved = [[NSString alloc] initWithFormat:#"$ %.02f", moneySaved];
self.differenceField.text = theMoneySaved;
}
-(IBAction)removeKeyboard
{
[self.productField resignFirstResponder];
[self.price1Field resignFirstResponder];
[self.discount1P1Field resignFirstResponder];
[self.discount2P1Field resignFirstResponder];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (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.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ProductTableViewCell";
ProductCell *cell = (ProductCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLabel = [[NSBundle mainBundle] loadNibNamed:#"ProductTableViewCell" owner:self options:nil];
for (id currentObject in topLabel) {
if ([currentObject isKindOfClass:[ProductCell class]]) {
cell = (ProductCell *) currentObject;
break;
}
}
}
return cell;
}
#end
First of all, I assume you are using a custom UITableViewCell, which has a textfield as one of it's parameters.
I would suggest making an associated model with these cells, which has a parameter which stores the value of the textfield every time the user enters in new information. Something like:
#interface TableViewCellModel : NSObject {
NSString * _valueOfTextfield;
}
#property (nonatomic, retain) NSString * valueOfTextfield;
#end
#implementation TableViewCellModel
#synthesize valueOfTextfield = _valueOfTextfield;
#end
Then, when the textfield is pressed, and the user enters in the information and resigns the textfield, update the associated model of the cell to store the value of the textfield.
When you want to show the TOTAL of the textfields in all the cells, just look at each of the cells corresponding models, and check if the valueOfTextfield property is nil or not.
One warning though, if each of the custom UITableViewCells has their own textfield, you could have some issues with performance, as well as your touch events in the cells. You may want to look into having a singleton class which handles the textfields separately, and each one of the custom cells having a reference to this singleton class.
EDIT: I have played with some code, and I think I have what you want now. You'll need a few files, and this gets a bit long. They will be in .h, then .m pairs.
#interface TableViewModel : NSObject {
int _index;
NSString * _textFieldValue;
}
#property (nonatomic, assign) int index;
#property (nonatomic, retain) NSString * textFieldValue;
#end
#import "TableViewModel.h"
#implementation TableViewModel
#synthesize index = _index;
#synthesize textFieldValue = _textFieldValue;
#end
Then,
#import <UIKit/UIKit.h>
#class TableViewModel;
#interface TableViewCell : UITableViewCell {
IBOutlet UILabel * _label;
}
#property (nonatomic, retain) TableViewModel * tableViewModel;
- (IBAction)useTextField;
#end
#import "TableViewCell.h"
#import "TableViewModel.h"
#import "AppDelegate.h"
#implementation TableViewCell
- (void)dealloc; {
[super dealloc];
}
- (void)setTableViewModel:(TableViewModel *)tableViewModel; {
_label.text = [tableViewModel textFieldValue];
}
- (TableViewModel *)tableViewModel; {
return nil;
}
- (IBAction)useTextField; {
[[AppDelegate appDelegate] useTextFieldForIndex:[self.tableViewModel index]];
}
#end
and finally,
#import <UIKit/UIKit.h>
#class TableViewCell;
#interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate> {
int _index;
NSMutableArray * _items;
IBOutlet TableViewCell * _cell;
IBOutlet UITableView * _tableView;
IBOutlet UITextField * _textField;
}
- (void)useTextFieldForIndex:(int)aIndex;
#end
#import "ViewController.h"
#import "TableViewModel.h"
#import "TableViewCell.h"
#implementation ViewController
- (void)dealloc; {
[_items release];
[super dealloc];
}
#pragma mark - View lifecycle
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad; {
[super viewDidLoad];
// This is an example of how to fill in the _items array with Models
_items = [[NSMutableArray alloc] init];
TableViewModel * model = [[TableViewModel alloc] init];
model.textFieldValue = #"1";
model.index = 0;
[_items addObject:model];
[model release];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField; {
TableViewModel * model = [_items objectAtIndex:_index];
model.textFieldValue = [_textField.text retain];
[_items replaceObjectAtIndex:_index withObject:model];
[_tableView reloadData];
[_textField resignFirstResponder];
return YES;
}
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; {
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; {
return 100;//This should be whatever the height of the cell is!
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; {
return [_items count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; {
NSString * cellIdentifier = #"TableViewCell";
TableViewCell * cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:cellIdentifier owner:self options:nil]; // hooks up _cell for us
cell = _cell;
}
cell.tableViewModel = ((TableViewModel *) [_items objectAtIndex:indexPath.row]);
return cell;
}
- (void)useTextFieldForIndex:(int)aIndex; {
_index = aIndex;
[_textField becomeFirstResponder];
}
#end
I assume that you know how to hook up the nibs, but if you need any more help, just ask. Also, you'll need to add these 2 methods to the AppDelegate.
+ (AppDelegate *)appDelegate; {
return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (void)useTextFieldForIndex:(int)aIndex; {
[self.viewController useTextFieldForIndex:aIndex];
}
This will allow the AppDelegate to pass the actions to have the textfield actions in only one view controller. It also should help with performance. To give a bit of explanation, _items holds all of the models which are used in the tableview. (Side note: when you want the user to add a new cell, all you need to do is add a new model to this array.)
The action: - (IBAction)useTextField; is attached to a clear button, and when it is pushed, it tells the AppDelegate to tell the ViewController to bring up the keyboard, and once you are done with it, you update the model as the index of the cell that was pressed, and reload the tableview.
You can then customize the cells the way you want, and make sure that you match the models as well.
To add up the values in the Models, you need only use:
double sum = 0;
for(TableViewCellModel * model in _items){
sum += [model.valueOfTextfield doubleValue];
}
Hope that helps!

pushViewController memory leak

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