I guys,
I am fighting with a problem since some days and wanted to get your assistance.
I have an RSS file on a server which gets parsed normally. Basically it's about shows, concerts, gigs of a band. That's why I have created the Show-Class:
Show.h:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface Show : NSObject {
NSString* gigName;
NSString* date;
NSString* place;
NSString* door;
NSString* time;
NSString* bands;
NSString* entry;
NSString* query;
NSString* flyer;
NSString* type;
}
- (id)init:(NSString*)gigName date:(NSString*)date place:(NSString*)place door:(NSString*)door time:(NSString*)time bands:(NSString*)bands
entry:(NSString*)entry query:(NSString*)query flyer:(NSString*)flyer type:(NSString*)type;
#property (nonatomic, retain) NSString* gigName;
#property (nonatomic, retain) NSString* date;
#property (nonatomic, retain) NSString* place;
#property (nonatomic, retain) NSString* door;
#property (nonatomic, retain) NSString* time;
#property (nonatomic, retain) NSString* bands;
#property (nonatomic, retain) NSString* entry;
#property (nonatomic, retain) NSString* query;
#property (nonatomic, retain) NSString* flyer;
#property (nonatomic, retain) NSString* type;
#end
and the Show.m:
#import "Show.h"
#implementation Show
#synthesize gigName, date , place, door, time, bands, entry, query, flyer, type;
- (id)init:(NSString*)_gigName date:(NSString*)_date place:(NSString*)_place door:(NSString*)_door time:(NSString*)_time bands:(NSString*)_bands
entry:(NSString*)_entry query:(NSString*)_query flyer:(NSString*)_flyer type:(NSString*)_type {
//if (self = [super init]) {
self = [super init];
if(self) {
gigName = _gigName;
date = _date;
place = _place;
door = _door;
time = _time;
bands = _bands;
entry = _entry;
query = _query;
flyer = _flyer;
type = _type;
}
return self;
}
- (void)dealloc {
[super dealloc];
}
#end
In my TourViewController (which is a table view) i have created this:
- (void)viewDidLoad {
[super viewDidLoad];
//Initialize the array.
listOfItems = [[NSMutableArray alloc] init];
pastShowArray = [NSMutableArray arrayWithCapacity:[stories count]]; // needs to be mutable
futureShowArray = [NSMutableArray arrayWithCapacity:[stories count]]; // needs to be mutable
for(int i = 0; i < [stories count]; i++) {
// get fields from story parser object
gigName = [[stories objectAtIndex:i] objectForKey:#"gig"];
type = [[stories objectAtIndex:i] objectForKey:#"type"];
date = [[stories objectAtIndex:i] objectForKey:#"date"];
place = [[stories objectAtIndex:i] objectForKey:#"place"];
door = [[stories objectAtIndex:i] objectForKey:#"door"];
time = [[stories objectAtIndex:i] objectForKey:#"time"];
bands = [[stories objectAtIndex:i] objectForKey:#"bands"];
entry = [[stories objectAtIndex:i] objectForKey:#"entry"];
query = [[stories objectAtIndex:i] objectForKey:#"query"];
flyer = [[stories objectAtIndex:i] objectForKey:#"flyer"];
// remove unnecessary whitespaces
gigName = [gigName stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
type = [type stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
date = [date stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
place = [place stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
door = [door stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
time = [time stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
bands = [bands stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
entry = [entry stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
query = [query stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
flyer = [flyer stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(gigName);
NSLog(type);
Show* show = [[Show alloc] init:gigName date:date place:place door:door time:time bands:bands entry:entry query:query flyer:flyer type:type];
if([type isEqualToString:#"past"]) {
// fill past show array
NSLog(#"adding past object now");
[pastShowArray addObject:show];
} else {
// fill future show array
NSLog(#"adding future object now");
[futureShowArray addObject:show];
}
}
NSMutableDictionary *pastShowsArrayDict = [NSMutableDictionary dictionaryWithObject:pastShowArray forKey:#"Show"];
NSLog(#"added past show array to pastshowarraydict");
NSMutableDictionary *futureShowsArrayDict = [NSMutableDictionary dictionaryWithObject:futureShowArray forKey:#"Show"];
NSLog(#"added future show array to futureshowarraydict");
[listOfItems addObject:pastShowsArrayDict];
[listOfItems addObject:futureShowsArrayDict];
//Set the title
self.navigationItem.title = #"Tour";
}
As far as I can tell, that worked all without problems. Now I want to show the "gigName" of the show in the table. For this I need to get the show object from the NSDictionary. I have this but it crashes:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
NSLog(#"try to set up cell");
//First get the dictionary object
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:#"Show"];
Show *show = [array objectAtIndex:indexPath.row];
NSLog(show.gigName);
cell.text = show.gigName;
return cell;
}
Error Output:
2011-02-14 16:32:44.462 All in Vain [405:307] try to set up cell
terminate called after throwing an instance of 'NSException'
Program received signal: “SIGABRT”.
Can you guys tell me how I can get the show object and set the table text to show.gigName?
Any help is appreaciated. Thank you,
cheers,
doonot
In your init:... for the Show object you need to make it:
self.gigName = _gigName;
self.date = _date;
self.place = _place;
self.door = _door;
self.time = _time;
self.bands = _bands;
self.entry = _entry;
self.query = _query;
self.flyer = _flyer;
self.type = _type;
so that each of them are retained (or do gigName = [_gigName retain]; but then you loose the release if it was not empty).
You may also have the same problem in the view controller and the way the variables are being set there but without seeing more I can't be sure.
Try to change this :
cell.text = show.gigName;
into :
cell.textLabel.text = show.gigName;
Related
I receive I EXC_BAD_ACCESS but i can't understand why.
this is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
TDBadgedCell *cell = [[[TDBadgedCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
SubscriptionArray * element =[reader.subscriptions objectAtIndex:[indexPath row]];
[cell.textLabel setText:element.title]; // <--- error at this line of code
return cell;
}
reader.subscritions is NSMutableArray that contains 81 elements ( I'm sure verificated with a NSLog) but when I try to get set the title I have this error... why?
SubscritionArray is a custom class that contains 3 string and 1 int.
Custom class:
header
#import <Foundation/Foundation.h>
#interface SubscriptionArray : NSObject{
NSString *title;
NSString *source;
NSString *htmlUrl;
NSInteger count;
}
#property (nonatomic,retain) NSString *title;
#property (nonatomic,retain) NSString *source;
#property (nonatomic,retain) NSString *htmlUrl;
#property (nonatomic) NSInteger count;
#end
implementation:
#import "SubscriptionArray.h"
#implementation SubscriptionArray
#synthesize title,source,htmlUrl,count;
-(void)dealloc{
[title release];
[source release];
[htmlUrl release];
}
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
title = [[decoder decodeObjectForKey:#"title"] retain];
source = [[decoder decodeObjectForKey:#"source"] retain];
htmlUrl = [[decoder decodeObjectForKey:#"htmlUrl"] retain];
//count = [decoder decodeIntForKey:#"count"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
if (title) [encoder encodeObject:title forKey:#"title"];
if (source) [encoder encodeObject:source forKey:#"source"];
if (htmlUrl) [encoder encodeObject:htmlUrl forKey:#"htmlUrl"];
//if (count) [encoder encodeInteger:count forKey:#"count"];
}
#end
EDIT
Tha's what I get
* -[__NSArrayM objectAtIndex:]: message sent to deallocated instance 0xe5a8260
And that's how I set the NSMutableArray
subscriptions = [[NSMutableArray alloc]init];
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//make a file name to write the data to using the
//documents directory:
NSString *fullFileName = [NSString stringWithFormat:#"%#/subscriptions", documentsDirectory];
[subscriptions removeAllObjects];
subscriptions = [NSKeyedUnarchiver unarchiveObjectWithFile:fullFileName];
I'd venture to say that your array of subscription elements isn't matching up with your row indexes (just a guess). Suggest that you set a debugger breakpoint immediately after you've declared 'element' and before you attempt to set the label. You should be able to see if you have actually obtained one of your SubscriptionArray objets...
The mutable array in reader.subscriptions is getting deallocated before you attempt to reference it in tableView:cellForRowAtIndexPath:. Make sure that the subscriptions array is properly retained or copied by the reader, and that you're not overreleasing it by sending an extra release or autorelease message somewhere. It might help to post the relevant code from the class of the reader instance.
I tried almost everything before posting (google, Apple Dev Doc etc.). I hope I did not miss anything before posting..
I already built a working JSON <-> Webservice <-> iPhone login.
with the following code:
NSString *responseString = [[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]autorelease];
NSDictionary *jsonDict = [responseString JSONValue];
NSString *loginResult = [jsonDict valueForKey:#"LoginResult"];
loginResult is the name of the employee: e.g "Henning Wenger"
The corresponding JSON looks like this:
{"LoginResult":"S:00000412"}
Now I have a more complex task which I can´t manage to figure a way through:
I´m getting the following JSON from the webservice:
{"GetTeamPresentStatusResult"[
{"Firstname":"Steffen","Id":"00000456","IsPresent":"true","Lastname":"Polker"},
{"Firstname":"Erich","Id":"00000455","IsPresent":"true","Lastname":"Welter"},
{"Firstname":"Titus","Id":"00000454","IsPresent":"true","Lastname":"Sommerbeck"}, {"Firstname":"Ruediger","Id":"00000453","IsPresent":"true","Lastname":"Oelmann"},{"Firstname":"Heinz","Id":"00000452","IsPresent":"true","Lastname":"Radelfs"},{"Firstname":"Franz","Id":"00000451","IsPresent":"true","Lastname":"Wippermann"},{"Firstname":"Klaus-Dieter","Id":"00000450","IsPresent":"true","Lastname":"Just"},{"Firstname":"Alan","Id":"00000412","IsPresent":"true","Lastname":"Turing"},{"Firstname":"Konrad","Id":"00000138","IsPresent":"true","Lastname":"Zuse"},{"Firstname":"Marius","Id":"00000112","IsPresent":"true","Lastname":"Sandmann"}]}
My code for handling this starts with:
NSDictionary *jsonDict = [responseString JSONValue];
NSArray *teamStatus = [jsonDict objectForKey:#"GetTeamPresentStatusResult"];
[self BuildDataSource: nil :teamStatus];
teamStatus now contains 10 key/value pairs.
Here is how I tried to build up the datasource for my table:
- (void)BuildDataSource: (id) sender: (NSArray*)teamStatusData{
teamStatusMutableArray = [[NSMutableArray alloc]init];
teamStatusDataSection = [[NSArray alloc]initWithArray:teamStatusData];
teamStatusDictSectionOne = [NSDictionary dictionaryWithObject:teamStatusDataSection forKey:#"OrgUnits"];
[teamStatusMutableArray addObject:teamStatusDictSectionOne];
[tblView reloadData];
}
I can not manage to figure out which way to go from here to get the data how I need it.
Do I need different Arrays where one contains the firstname/value and another one that contains lastname/value? If yes, how do I do that?
Here are some lines I´ve tried so far which did not have helped:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
//First get the dictionary object
NSDictionary *dictionary = [teamStatusMutableArray objectAtIndex:indexPath.section];
NSString *testString = [dictionary valueForKey:#"Firstname"];
NSArray *testarray = [dictionary objectForKey:#"OrgUnits"];
NSString *test = [testarray JSONRepresentation];
test = [test stringByReplacingOccurrencesOfString:#"[" withString:#""];
test = [test stringByReplacingOccurrencesOfString:#"]" withString:#""];
NSDictionary *jsonDict = [test JSONValue];
}
What I need is to have a Datasource with the Employee Names that I can bind to a Table. From there I think I can make my way without additional help.
I´m coming from the .NET (C#) world and maybe this confuses me too much.
Thank you so much..
Henning
If you need further details please ask!
Details for SPtail:
Here is the .h file:
#import <UIKit/UIKit.h>
#import "RootViewController.h"
#import "EmployeeDetails.h"
#interface OrgUnitAA:NSObject {
NSString *FirstName;
NSString *Id;
NSString *IsPresent;
NSString *LastName;
}
#property (nonatomic, retain) NSString *FirstName;
#property (nonatomic, retain) NSString *Id;
#property (nonatomic, retain) NSString *IsPresent;
#property (nonatomic, retain) NSString *LastName;
#end
#interface TeamStatusView : UIViewController {
UITableView *tblView;
NSMutableArray *teamStatusMutableArray;
NSArray *teamStatusDataSection;
NSDictionary *teamStatusDictSectionOne;
UIViewController *EmployeeDetails;
UIViewController *RootViewController;
NSMutableData *responseData;
}
#property (nonatomic, retain) IBOutlet UITableView *tblView;
#property (nonatomic, retain) NSArray *teamStatusMutableArray;
#property (nonatomic, retain) NSMutableArray *dummyMutableArrayTimeQuota;
#property (nonatomic, retain) NSArray *teamStatusDataSection;
#property (nonatomic, retain) NSDictionary *teamStatusDictSectionOne;
#property (nonatomic, retain) IBOutlet UIViewController *RootViewController;
#property (nonatomic, retain) IBOutlet UIViewController *EmployeeDetails;
- (void)GetTeamStatus: id;
- (void)BuildDataSource: id: (NSArray*)teamStatusData;
#end
Hey the array returned by the web service contains dictionaries, which is obvious.
Instead of using different arrays for each property, you can create a class which extends NSObject and convert each dictionary so that you will have the objects inside an array instead of dictionaries. In this case:
#interface OrgUnit:NSObject {
NSString *FirstName;
NSNumber *Id;
bool IsPresent;
NSString *LastName;
}
//And all the properties here
After this you can convert dictionaries into object by using
OrgUnit *unit = [[OrgUnit alloc] init];
[unit setValuesForKeysWithDictionary:dictionary];
PS: The variable names in the object should be same as that of the keys in dictionary
I´ve found a solution.
This is the way I get to the data:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
NSDictionary *dictionary = [teamStatusMutableArray objectAtIndex:indexPath.section];
NSArray *teamStatus = [dictionary objectForKey:#"OrgUnits"];
NSEnumerator *e = [teamStatus objectEnumerator];
id object;
int i = 0;
while (object = [e nextObject]) {
if(i == indexPath.row)
{
NSString *firstname = [object valueForKey:#"Firstname"];
NSString *lastname = [object valueForKey:#"Lastname"];
NSString *fullname = [NSString stringWithFormat:#"%#%#%#", lastname, #", ", firstname];
cell.textLabel.text = fullname;
bool isPresent = [object valueForKey:#"IsPresent"];
if(isPresent == true)
{
cell.imageView.image = [UIImage imageNamed:#"GreenBall.png"];
}
else
{
cell.imageView.image = [UIImage imageNamed:#"RedBall.png"];
}
break;
}
i++;
}
[aiActivity stopAnimating];
self.aiActivity.hidden = true;
return cell;
}
Could be just a typo.
Change this:
teamStatusDictSectionOne = [NSDictionary dictionaryWithObject:teamStatusDataSection forKey:#"OrgUnits"];
To this:
teamStatusDictSectionOne = [NSDictionary dictionaryWithObjects:teamStatusDataSection forKey:#"OrgUnits"];
The change is -dictionaryWithObjects. Plural. Obj-C is kinda finicky about that stuff.
Also, you are referencing indexPath.section when you build the individual cells. I think you should be referencing the row for the cell. The row should correlate to your array index.
NSInteger row = [indexPath row];
NSDictionary *dictionary = [teamStatusMutableArray objectAtIndex:row];
i declared a NSMutable array and assigned some values to it .
.h
NSMutableArray *imageDetailsFromCategory;
#property (nonatomic, retain) NSMutableArray *imageDetailsFromCategory;
.m
#synthesise imageDetailsFromCategory
in ViewDidLoad:
imageDetailsFromCategory = [[NSMutableArray alloc]init];
//assigning object to Array..working fine.showing two images.
imageDetailsFromCategory = [self getImageDetailsFromCategory:generatedString];
i had one problem that solved now. i have a problem that is i am passing this array to StaticCategoryWithMultiImagePopOver class.
StaticCategoryWithMultiImagePopOver *staticCategoryWithMultiImagePopOver = [[StaticCategoryWithMultiImagePopOver alloc] init];
[staticCategoryWithMultiImagePopOver setParentImageDetailsArray:imageDetailsFromCategory];
in StaticCategoryWithMultiImagePopOver.h
NSMutableArray *nsmResult;
#property (nonatomic,retain)NSMutableArray *nsmResult;
.m
#synthesize nsmResult
-(void)setParentImageDetailsArray:(NSMutableArray *)imageDetailsFromCategoryFromParent{
nsmResult=[[NSMutableArray alloc] init];
nsmResult=[imageDetailsFromCategoryFromParent retain];
}
the passed array hold a class object with some string variables at each index.
so i am getting this through the code:
- (UITableViewCell *)tableView:(UITableView *)tableView15 cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView15 dequeueReusableCellWithIdentifier:CellIdentifier];
// if (cell == nil) {
// cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
// }
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0];
SymbolTalkEntry *symbolTalkEntry = [[SymbolTalkEntry alloc]init];
symbolTalkEntry =[nsmResult objectAtIndex:indexPath.row];
NSString *imageNme = symbolTalkEntry.fileName; // *this line*
the above line is getting error.
array shows the count but the objects are out of scope..cant get the values ...
can any one tell me how can i access it...may i know what is the problem with me...
cellForRowAtIndexPath(its working fine)
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView15 cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView15 dequeueReusableCellWithIdentifier:CellIdentifier];
// if (cell == nil) {
// cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
// }
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0];
SymbolTalkEntry *symbolTalkEntry = [[SymbolTalkEntry alloc]init];
symbolTalkEntry =[nsmResult objectAtIndex:indexPath.row];
NSString *imageNme = symbolTalkEntry.fileName;
[symbolTalkEntry release];
//Display image from app bundle
NSString *path = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png",imageNme]];
cell.imageView.image= [UIImage imageWithContentsOfFile:path];
return cell;
}
-(NSInteger)number
This
nsmResult=[[NSMutableArray alloc] init];
nsmResult=[imageDetailsFromCategoryFromParent retain];
and this
SymbolTalkEntry *symbolTalkEntry = [[SymbolTalkEntry alloc]init];
symbolTalkEntry =[nsmResult objectAtIndex:indexPath.row];
are memory leaks.
About your problem: the object you get by
symbolTalkEntry =[nsmResult objectAtIndex:indexPath.row];
seems not to have a property fileName.
I think you should read a good book about Objective-C and Cocoa.
Actually it's the problem of the class which is inside the array.
I changed my class as this:
#import <Foundation/Foundation.h>
#interface SymbolTalkEntry : NSObject {
int categoryId;
NSString *runModeType;
NSString *sceneCategory;
NSString *fileName;
int isDefault;
int sortX;
int pathId;// 0 for appbundle 1 for document directry
}
#property (nonatomic, retain)NSString *runModeType;;
#property (nonatomic, retain)NSString *sceneCategory;
#property (nonatomic, retain)NSString *fileName;
-(id)init;
-(void) setCategoryId:(int) ctgId;
-(int)categoryId;
-(void) setRunModeType:(NSString *)rmType;
-(NSString *) runModeType;
-(void) setSceneCategory:(NSString *)scCategory;
-(NSString *) sceneCategory;
-(void) setFileName:(NSString *)Flname;
-(NSString *) fileName;
-(void) setIsDefault:(int) isDeft;
-(int)isDefault;
-(void) setSortX:(int) srtX;
-(int)sortX;
-(void) setPathId:(int) srtX;
-(int)pathId;
#end
[5:05:00 AM] Shamsudheen TK: #import "SymbolTalkEntry.h"
#implementation SymbolTalkEntry
#synthesize runModeType;
#synthesize sceneCategory;
#synthesize fileName;
-(id) init{
categoryId = 0;
runModeType = #"";
sceneCategory =#"";
fileName = #"";
isDefault = 0;
sortX =0;
pathId =0;
return self;
}
-(void) setCategoryId:(int) ctgId{
categoryId = ctgId;
}
-(int)categoryId{
return categoryId;
}
-(void) setRunModeType:(NSString *)rmType{
if (runModeType != rmType) {
[runModeType release ];
runModeType = [rmType retain];
}
}
-(NSString *) runModeType{
return runModeType;
}
-(void) setSceneCategory:(NSString *)scCategory{
if (sceneCategory != scCategory) {
[sceneCategory release];
sceneCategory = [scCategory retain];
}
}
-(NSString *) sceneCategory{
return sceneCategory;
}
-(void) setFileName:(NSString *)Flname{
if (fileName != Flname) {
[fileName release];
fileName = [Flname retain];
}
}
-(NSString *) fileName{
return fileName;
}
-(void) setIsDefault:(int) isDeft{
isDefault = isDeft;
}
-(int)isDefault{
return isDefault;
}
-(void) setSortX:(int) srtX{
sortX =srtX;
}
-(int)sortX{
return sortX;
}
-(void) setPathId:(int) srtX{
pathId = srtX;
}
-(int)pathId{
return pathId;
}
-(void)dealloc{
[categoryId release];
[runModeType release];
[sceneCategory release];
[fileName release];
[isDefault release];
[sortX release];
[pathId release];
}
#end
and set the values using the set methods that I wrote (eg: [classobj setCategoryId:1]).
now out of scope is solved.....
I have a problem with a NSMutableArray... After I fill the NSMutableArray in my function (readRoutes) I can't extract the objects.... Inside the readRoutes function I can... I can't figure where is the problem..
First the NSMutableArray is fill with Route objects in the readRoutes method...(Inside RoutesListView file) (I need to fill after TableView cells with these Route objects...)
This is the Route.h file :
#interface Route : NSObject {
NSString *routeId;
NSString *routeDirection;
NSString *routeName;
NSString *routeCode;
}
#property (nonatomic,retain) NSString *routeId;
#property (nonatomic,retain) NSString *routeDirection;
#property (nonatomic,retain) NSString *routeName;
#property (nonatomic,retain) NSString *routeCode;
-(id)initWithName:(NSString *)name direction:(NSString *)d routeId:(NSString *)rid code:(NSString *)c;
#end
The Route.m file:
#import "Route.h"
#implementation Route
#synthesize routeId;
#synthesize routeDirection;
#synthesize routeName;
#synthesize routeCode;
-(id)initWithName:(NSString *)name direction:(NSString *)d routeId:(NSString *)rid code:(NSString *)c{
self.routeId=rid;
self.routeName=name;
self.routeDirection=d;
self.routeCode=c;
return self;
}
#end
Now this is the RoutesListView.h file (a UITableViewController)
#import <UIKit/UIKit.h>
#import "Route.h"
#interface RoutesListView : UITableViewController <UITableViewDelegate,UITableViewDataSource> {
NSMutableArray *routeArray;
NSString *dbName;
NSString *dbPath;
}
#property (nonatomic,retain) NSMutableArray *routeArray;
#property (nonatomic,retain) NSString *dbName;
#property (nonatomic,retain) NSString *dbPath;
-(void)readRoutes;
#end
Inside the RoutesListView.m file :
#import "RoutesListView.h"
#import "Route.h"
#import <sqlite3.h>
#implementation RoutesListView
#synthesize routeArray;
#synthesize dbName,dbPath;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
dbName = #"data.db";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
dbPath = [documentsDir stringByAppendingPathComponent:dbName];
routeId =[[NSMutableArray alloc] init];
//routeArray
NSMutableArray * array = [[NSMutableArray alloc] init];
self.routeArray = array;
[array release];
[self readRoutes];
[super viewDidLoad];
}
INSIDE THE readRoutes method when I fill the NSMutableArray (The method work fine...):
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *aId = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
NSString *aDirection =[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *aCode = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
Route *maRoute = [[Route alloc] initWithName:aName direction:aDirection routeId:aId code:aCode];
// I fill the NSMutableArray here...
[routeArray addObject:maRoute];
[maRoute release];
[aId release];
[aDirection release];
[aName release];
[aCode release];
}
FINALLY WHEN I SET THE CELL TEXTLABEL...IT CRASH! :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
NSUInteger row = [indexPath row];
Route *myRoute = (Route *)[routeArray objectAtIndex:row];
cell.textLabel.text = myRoute.routeName;
[myRoute release];
return cell;
}
Help me to understand... I lost my hair on that...
Thanks
Maxime
You are over releasing several objects which will usually cause your application to crash. Also your init function is not properly implemented inside of your Route.m file. Make the following changes.
#import "Route.h"
#implementation Route
#synthesize routeId;
#synthesize routeDirection;
#synthesize routeName;
#synthesize routeCode;
-(id)initWithName:(NSString *)name direction:(NSString *)d routeId:(NSString *)rid code:(NSString *)c{
//Must call supers implementation of init
self = [super init];
if(self)
{
self.routeId=rid;
self.routeName=name;
self.routeDirection=d;
self.routeCode=c;
}
return self;
}
#end
Next you are over releasing objects inside of readRoutes
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *aId = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
NSString *aDirection =[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *aCode = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
Route *maRoute = [[Route alloc] initWithName:aName direction:aDirection routeId:aId code:aCode];
// I fill the NSMutableArray here...
[routeArray addObject:maRoute];
[maRoute release]; //This is right you called alloc/init
[aId release]; //This is wrong never retained,copy or alloc/init
[aDirection release];//Dont release here either
[aName release]; //Dont release
[aCode release]; //Dont release
}
And finally you are over releasing the route inside of the following code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
NSUInteger row = [indexPath row];
Route *myRoute = (Route *)[routeArray objectAtIndex:row];
cell.textLabel.text = myRoute.routeName;
[myRoute release]; //Do not release route here
return cell;
}
I am writing a program which prints the reverse of a string in a textfield, taking input text from the other textfield. When I press enter after entering text into one textfield the result(reverse) should be dispalyed in the other text field.
I have tried like this, but am getting weird results.
.h file:
#import <UIKit/UIKit.h>
#interface reverseVC : UIViewController {
UITextField *textEntered;
UITextField *textDisplay;
}
#property (nonatomic,retain) IBOutlet UITextField *textDisplay;
#property (nonatomic,retain) IBOutlet UITextField *textEntered;
- (NSMutableArray*) stringReverse;
- (IBAction) enter;
#end
.m file
- (NSMutableArray *) stringReverse
{
NSString *value = textEntered.text;
NSArray *tempArray = [[[NSArray alloc] initWithObjects:value,nil] autorelease];
NSMutableArray *arr = [[[NSMutableArray alloc] init] autorelease];
for (int i=[tempArray count]-1; i>=0; i--)
{
[arr addObject:[tempArray objectAtIndex:i]];
NSLog(#"the object is:%c",arr);
}
return arr;
}
-(IBAction)enter
{
textDisplay.text = [NSString stringWithFormat:#"%c",[self stringReverse]];
}
Earlier got warnings like SIG_ABT and EXE_BAD_ACCESS before placing nil and autorelease in array initialisations. Now the warnings are solved but results undesiredly.
Where am I going wrong?
You insert the NSString object in your array. Its count is 1. You have to go from the end of the string to the beginning and append the character to a new string. You ca do it like this:
-(NSString*)reverseString:(NSString*)string {
NSMutableString *reversedString;
int length = [string length];
reversedString = [NSMutableString stringWithCapacity:length];
while (length--) {
[reversedString appendFormat:#"%C", [string characterAtIndex:length]];
}
return reversedString;
}
Another way to reverse strings is to use the reverse string enumerator.
- (NSString *)reverseString:(NSString *)string {
NSMutableString *reversedString = [[NSMutableString alloc] init];
NSRange fullRange = [string rangeOfString:string];
NSStringEnumerationOptions enumerationOptions = (NSStringEnumerationReverse | NSStringEnumerationByComposedCharacterSequences);
[string enumerateSubstringsInRange:fullRange options:enumerationOptions usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[reversedString appendString:substring];
}];
return reversedString;
}
use this
NSString *str=textEntered.text;//
NSMutableArray *temp=[[NSMutableArray alloc] init];
for(int i=0;i<[str length];i++)
{
[temp addObject:[NSString stringWithFormat:#"%c",[str characterAtIndex:i]]];
}
temp = [NSMutableArray arrayWithArray:[[temp reverseObjectEnumerator] allObjects]];
NSString *reverseString=#"";
for(int i=0;i<[temp count];i++)
{
reverseString=[NSString stringWithFormat:#"%#%#",reverseString,[temp objectAtIndex:i]];
}
NSLog(#"%#",reverseString);
I revers my strings with a few lines of code. Rather late, but just putting it out there :)
- (NSString*) reverseMyString:(NSString*)theString
{
NSString *final = #"";
for(int i = theString.length-1; i>=0; i--)
final = [NSString stringWithFormat:#"%#%c", final, [theString characterAtIndex:i]];
return final;
}
NSString *str = #"hello";
int length = [str length];
NSLog(#"%d",length);
NSMutableString *rev = [[NSMutableString alloc] initWithCapacity:[str length]];
while (length > 0) {
--length;
[rev appendString:[NSString stringWithFormat:#"%c", [str characterAtIndex:length]]];
}
NSLog(#"%#", rev);
Using characterAtIndex doesn't work well with non-ascii characters.
- (NSString *)reverseMyString:(NSString *)string {
NSString *output = [[NSString alloc] init];
for(int i = string.length-1; i>=0; i--) {
output = [output stringByAppendingString:[string substringWithRange:NSMakeRange(i, 1)]];
}
return output;
}