It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I have created a custom class for EmployeeInfo:
#interface METEmployee : NSObject
#property (weak, nonatomic) NSString *EmpNo;
#property (weak, nonatomic) NSString *FirstName;
#property (weak, nonatomic) NSString *MiddleName;
#property (weak, nonatomic) NSString *LastName;
#property (weak, nonatomic) NSString *Department;
#property (weak, nonatomic) NSString *HireDate;
#property (weak, nonatomic) NSString *JobTitle;
#property (weak, nonatomic) NSString *SupervisorNumber;
#property (weak, nonatomic) NSString *SupLastName;
#property (weak, nonatomic) NSString *SupFirstName;
#property (weak, nonatomic) NSString *MobilePhone;
#property (weak, nonatomic) NSString *EmailAddress;
#property (weak, nonatomic) NSString *DeskPhone;
#property (weak, nonatomic) NSString *EmployeeType;
#property (weak, nonatomic) NSString *Location;
#end
Then in my view controller.h I have created:
NSMutableArray *theemplyees;
#property(nonatomic, retain) NSMutableArray *theemplyees;
Synthesize is .m:
#synthesize theemplyees
Then in ViewDidLoad, init and call to populate it:
theemplyees = [[NSMutableArray alloc] init];
[self getEmps];
In getEmps, I add the records to the array:
results = [database executeQuery:#"select * from EmpInfo order by LastName"];
while([results next]) {
METEmployee *empInfo = [METEmployee alloc];
empInfo.EmpNo = [results stringForColumn:#"EmpNo"];
empInfo.FirstName = [results stringForColumn:#"FirstName"];
empInfo.MiddleName = [results stringForColumn:#"MiddleName"];
empInfo.LastName = [results stringForColumn:#"LastName"];
empInfo.Department = [results stringForColumn:#"Department"];
empInfo.HireDate = [results stringForColumn:#"HireDate"];
empInfo.JobTitle = [results stringForColumn:#"JobTitle"];
empInfo.SupervisorNumber = [results stringForColumn:#"SupervisorNumber"];
empInfo.SupFirstName = [results stringForColumn:#"SupFirstName"];
empInfo.SupLastName = [results stringForColumn:#"SupLastName"];
empInfo.MobilePhone = [results stringForColumn:#"MobilePhone"];
empInfo.EmailAddress = [results stringForColumn:#"EmailAddress"];
empInfo.DeskPhone = [results stringForColumn:#"DeskPhone"];
empInfo.EmployeeType = [results stringForColumn:#"EmployeeType"];
empInfo.Location = [results stringForColumn:#"Location"];
[theemplyees addObject:empInfo];
}
Everything works fine for populating the table for the the first screen full of records:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
METEmpTableViewCell *cell = (METEmpTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"myCell"];
cell.lblFirstName.text = [[theemplyees objectAtIndex:indexPath.row] valueForKey:#"FirstName"];
cell.lblLastName.text = [[theemplyees objectAtIndex:indexPath.row] valueForKey:#"LastName"];
cell.lblDepartment.text = [[theemplyees objectAtIndex:indexPath.row] valueForKey:#"Department"];
NSString* picName = [NSString stringWithFormat:#"%#.jpg", [[theemplyees objectAtIndex:indexPath.row] valueForKey:#"EmpNo"]];
#try {
cell.empPicture.image = [UIImage imageNamed:picName];
}
#catch (NSException *exception) {
}
#finally {
}
return cell;
}
But if I attempt to scroll up or down on the Tableview, the array says the data is null...although it still shows the record count. If I resize my cell pn the table to smaller, it will populate more rows (that are visible) but once again any scrolling and they are gone.
Any thoughts or sugguestions is greatly appreciated. Thanks in advance for any and all help!
Geo...
You all have weak properties which means that all of the strings are instantly deallocated, since nothing is retaining them. Change it to this and try:
#property (nonatomic, strong) NSString *theString;
Also, you want to initialize your NSMutableArray like so (you're missing the init method):
NSMutableArray *array = [[NSMutableArray alloc] init];
Related
What I like to do:
User enters 10 in UITextField and tap on UIButton.
UILabel shows 10 and UITextField goes blank.
User enters 5 in UITextField and tap on UIButton.
UILable shows 15 and UITextField goes blank again.
With following code I get the entered number saved and shown in the label but how can I tell the array to add and show me total and not just the very first number I entered?
h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (nonatomic, strong) IBOutlet UILabel *label;
#property (nonatomic, strong) IBOutlet UITextField *field;
#property (nonatomic, strong) NSString *dataFilePath;
#property (nonatomic, strong) NSString *docsDir;
#property (nonatomic, strong) NSArray *dirPaths;
#property (nonatomic, strong) NSFileManager *fileMgr;
#property (nonatomic, strong) NSMutableArray *array;
- (IBAction)saveNumber:(id)sender;
#end
m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize label, field, dataFilePath, docsDir, fileMgr, dirPaths, array;
- (void)viewDidLoad
{
[super viewDidLoad];
fileMgr = [NSFileManager defaultManager];
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
dataFilePath = [[NSString alloc]initWithString:[docsDir stringByAppendingPathComponent:#"data.archive"]];
if ([fileMgr fileExistsAtPath:dataFilePath])
{
array = [NSKeyedUnarchiver unarchiveObjectWithFile:dataFilePath];
self.label.text = [array objectAtIndex:0];
}
else
{
array = [[NSMutableArray alloc] init];
}
}
- (IBAction)saveNumber:(id)sender
{
[array addObject:self.field.text];
[NSKeyedArchiver archiveRootObject:array toFile:dataFilePath];
[field setText:#""];
[label setText:[array objectAtIndex:0]];
}
You need to iterate through all the values and add them to a running total. Have a look at this:-
- (IBAction)saveNumber:(id)sender
{
[array addObject:self.field.text];
[NSKeyedArchiver archiveRootObject:array toFile:dataFilePath];
[field setText:#""];
// Create an enumerator from the array to easily iterate
NSEnumerator *e = [array objectEnumerator];
// Create a running total and temp string
int total = 0;
NSString stringNumber;
// Enumerate through all elements of the array
while (stringNumber = [e nextObject]) {
// Add current number to the running total
total += [stringNumber intValue];
}
// Now set the label to the total of all numbers
[label setText:[NSString stringWithFormat:#"%d",total];
}
I've commented the code for readability.
Iterate over the array, get all values as numbers using [string intValue] and sum them up in another variable. Then add the calculated value to the label using a formatted string like [NSString stringWithFormat: #"%d"].
I'm getting a memory leak with instruments in a class that I've created. This is the class:
.h
#import <Foundation/Foundation.h>
#interface RDItem : NSObject {
}
#property int Id;
#property (nonatomic, retain) NSString *nombre;
#property (nonatomic, retain) NSString *thumbnail;
#property (nonatomic, retain) NSString *thumbnailPush;
#property int defaultColorId;
#property int idTema;
#property (nonatomic, retain) NSString *selectedFrame;
#property (nonatomic, retain) NSString *mergedFrame;
#property (nonatomic, retain) NSMutableArray *colors;
#property (nonatomic, retain) NSMutableArray *textures;
#property (nonatomic, retain) NSMutableArray *styles;
-(void)initialize;
#end
.m
#import "RDItem.h"
#implementation RDItem
#synthesize Id;
#synthesize nombre;
#synthesize thumbnail;
#synthesize thumbnailPush;
#synthesize defaultColorId;
#synthesize idTema;
#synthesize selectedFrame;
#synthesize mergedFrame;
#synthesize colors;
#synthesize textures;
#synthesize styles;
-(void)initialize
{
colors = [[NSMutableArray alloc] init];
textures = [[NSMutableArray alloc] init];
styles = [[NSMutableArray alloc] init];
}
-(void)dealloc
{
[colors release];
[textures release];
[styles release];
}
#end
This class have 3 NSMutableArray where I'll store data. In order to prepare and initialice this class, I've developed the method initialize where the 3 arrays are created. In dealloc are released.
The leaks tool detects a leak each time this class is used because the initialize method.
Which is the best way to initialize these arrays?
Thanks.
EDIT
Hi I've solved the leak with RDItem but now appears another lear in a very similar class:
.h
#import <Foundation/Foundation.h>
#interface RDTema : NSObject {
}
#property int Id;
#property (nonatomic, retain) NSString *idManifest;
#property (nonatomic, retain) NSString *idTema;
#property (nonatomic, retain) NSString *nombre;
#property (nonatomic, retain) NSString *thumbnail;
#property (nonatomic, retain) NSString *thumbnailPush;
#property (nonatomic, retain) NSMutableArray *items;
#property (nonatomic, retain) NSMutableArray *colors;
#property (nonatomic, retain) NSMutableArray *textures;
#property (nonatomic, retain) NSMutableArray *styles;
-(void)initialize;
#end
.m
#import "RDTema.h"
#implementation RDTema
#synthesize Id;
#synthesize idManifest;
#synthesize idTema;
#synthesize nombre;
#synthesize thumbnail;
#synthesize thumbnailPush;
#synthesize items;
#synthesize colors;
#synthesize textures;
#synthesize styles;
-(void)initialize
{
/*
self.items = [[NSMutableArray alloc] init];
self.colors = [[NSMutableArray alloc] init];
self.textures = [[NSMutableArray alloc] init];
self.styles = [[NSMutableArray alloc] init];
*/
self.items = [NSMutableArray array];
self.colors = [NSMutableArray array];
self.textures = [NSMutableArray array];
self.styles = [NSMutableArray array];
}
-(void)dealloc
{
[idManifest release];
[idTema release];
[nombre release];
[thumbnail release];
[thumbnailPush release];
[items release];
[colors release];
[textures release];
[styles release];
[super dealloc];
}
Now I'm getting a leak in these lines:
self.items = [NSMutableArray array];
self.colors = [NSMutableArray array];
self.textures = [NSMutableArray array];
self.styles = [NSMutableArray array];
Anyone can explain why is happening in this class and not in RDItem class now? Are the same :(
Thanks.
This is a better suggested implementation
-(void)initialize
{
self.colors = [NSMutableArray array];
self.textures = [NSMutableArray array];
self.styles = [NSMutableArray array];
}
-(void)dealloc
{
self.colors = nil;
self.textures = nil;
self.styles = nil;
}
I think that you are getting the leak because you call your initialize message more than once and you are not releasing the variables.
Normally, you should use setters or getters to access your ivars, so the appropiate operations are called (like the release message before assigning a new value on setter).
And remember to call [super dealloc] as the last instruction for your dealloc ;)
Without seeing the code where you are initialising the RDItem i can't say for sure.
But i expect that you are not releasing your previous RDItem before creating your new one. So post the code where you are creating your RDItems so we can say for sure
I think, that leak are in arrays filling code, not init. For example, you alloc and init some NSString and put it in your NSMutable array without release or autorelease it. Or something like this. Make shure that you filling your arrays right way.
Just init them when you need it. Calling alloc and init holds to arrays whose content is nil. Call alloc initWithObjects: and fill the arrays.
I'm fairly new to the iOS platform and I'm having some issues with the memory management. I'm passing an object (a Trial) in through an initializer of a custom UIViewController class and when the UIViewController finally receives it, the object is nil. I was hoping someone could point me in the right direction. I've included some of the source code below.
Trial.h
#interface Trial : NSObject {
NSString *IRBNumber;
NSString *PI;
NSString *Sponsor;
NSString *ContactName;
NSString *ContactPhone;
NSString *ContactEmail;
NSString *Location;
NSString *Objective;
NSString *Eligibility;
NSString *Name;
NSString *DiseaseGroup;
NSString *Age;
}
#property (retain, nonatomic) NSString *IRBNumber;
#property (retain, nonatomic) NSString *PI;
#property (retain, nonatomic) NSString *Sponsor;
#property (retain, nonatomic) NSString *ContactName;
#property (retain, nonatomic) NSString *ContactEmail;
#property (retain, nonatomic) NSString *ContactPhone;
#property (retain, nonatomic) NSString *Location;
#property (retain, nonatomic) NSString *Objective;
#property (retain, nonatomic) NSString *Eligibility;
#property (retain, nonatomic) NSString *Name;
#property (retain, nonatomic) NSString *DiseaseGroup;
#property (retain, nonatomic) NSString *Age;
#end
DiseaseControllersViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Trial *trial = (Trial *)[dataArray objectAtIndex:indexPath.row];
TrialDetailController *detailViewController = [[TrialDetailController alloc] initWithNibNameAndTrial:#"TrialDetailController" bundle:nil trial:trial];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
[trial release];
}
Here's the definition of the initializer
-(id)initWithNibNameAndTrial: (NSString*)NibNameOrNil bundle:(NSBundle*)nibBundlerOrNil trial:(Trial *)inTrial {
self = [super initWithNibName:NibNameOrNil bundle:nibBundlerOrNil];
if(self) {
self.trial = inTrial;
}
return self;
}
TrialDetailController.h
#import "Trial.h"
#interface TrialDetailController : UITabBarController {
Trial *trial;
}
#property (nonatomic, retain) Trial *trial;
-(id)initWithNibNameAndTrial: (NSString*)NibNameOrNil bundle:(NSBundle*)nibBundlerOrNil trial:(Trial *)inTrial;
-(IBAction)objectiveTabItemClick:(id)sender;
-(IBAction)detailsTabItemClick:(id)sender;
#end
You should not use self.trial within the init-method. Make that trial = [inTrial retain];.
Then you should not import Trial.h in TrialDetailController.h, do that in TrialDetailController.m. Put a #class Trial; (a forward definition) above the #interface line in TrialDetailController.h.
My guess is that when your code does
Trial *trial = (Trial *)[dataArray objectAtIndex:indexPath.row];
the variable dataArray is nil. Then trial would be nil, too.
The [trial release]; shouldn't be there as 从善如流 is suggesting.
I cannot find any other problem.
Only you don't have to declare the property variable:
Trial *trial in your interface. A variable is created automatically when synthesizing (I expect you have #synthesize trial; somewhere).
I have a People class which holds various bits of into about a person. I would like to be able to identify what kind of person this is, so I thought I would try using a typedef enum for this since I have seen it done before and it seems like the cleanest solution. But, I am unsure how to declare this, then make it into a property.
.h
typedef enum {
kPersonTypeFaculty,
kPersonTypeStaff,
kPersonTypeSearch
} personType;
#interface Person : NSObject {
NSString *nameFirst;
NSString *nameLast;
NSString *email;
NSString *phone;
NSString *room;
NSString *status;
NSString *building;
NSString *department;
NSString *imageURL;
NSString *degree;
NSString *position;
NSString *bio;
NSString *education;
}
#property (nonatomic, retain) NSString *nameFirst;
#property (nonatomic, retain) NSString *nameLast;
#property (nonatomic, retain) NSString *email;
#property (nonatomic, retain) NSString *phone;
#property (nonatomic, retain) NSString *room;
#property (nonatomic, retain) NSString *status;
#property (nonatomic, retain) NSString *building;
#property (nonatomic, retain) NSString *department;
#property (nonatomic, retain) NSString *imageURL;
#property (nonatomic, retain) NSString *degree;
#property (nonatomic, retain) NSString *position;
#property (nonatomic, retain) NSString *bio;
#property (nonatomic, retain) NSString *education;
#end
.m
#import "Person.h"
#implementation Person
#synthesize nameFirst, nameLast, email, phone, room, status, building, department, imageURL, degree, position, bio, education;
- (void)dealloc {
[nameFirst release];
[nameLast release];
[email release];
[phone release];
[room release];
[status release];
[building release];
[department release];
[imageURL release];
[degree release];
[position release];
[bio release];
[education release];
[super dealloc];
}
#end
I want to be able to do something like:
Person *person = [[[Person alloc] init] autorelease];
person.nameFirst = #"Steve";
person.nameLast = #"Johnson";
person.personType = kPersonTypeStaff;
Am I missing a crucial part of this idea?
You define it like you would for any primitive type (like int or float). When you use typedef, you are telling the compiler that this name is a type which represents this. So, you would add an instance variable with that type (I capitalized the type in my post to distinguish it from the variable or property):
personType personType;
Then add a property definition:
#property (nonatomic) personType personType;
Then you synthesize it and use it:
#synthesize personType;
self.personType = kPersonTypeStaff;
A enum type is actually some type of integer which holds all of the values of the enum. By using typedef, you can specify that this integer should be one of the constants in the enum and nothing else, and the compiler can help enforce this. But, except for the variable type, you treat it exactly the same way you would an int type.
You add the following property:
#property (nonatomic) personType personType;
How to copy one NSString to another?
#interface MyData : NSObject
{
#private
//user's private info
NSInteger uID;
NSString *name;
NSString *surname;
NSString *email;
NSString *telephone;
//user's picture
UIImage *image;
}
#property (nonatomic, assign) int uID;
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *surname;
#property (nonatomic, retain) NSString *email;
#property (nonatomic, retain) NSString *telephone;
#property (nonatomic, retain) UIImage *image;
#end
I have two objects of this type. MyData *obj1, obj2;
First is initialized. Second I want to initialize with first.
obj2 = [obj1 copy]; //crashes
newData.surname = data.surname; //crashes to
newData.email = data.email;
newData.telephone = data.telephone;
I neeeeed a COPY of second object NOT RETAIN!!! Help please! Thanx!
you can use the NSString method stringWithString.
See also stringwithstring, what's the point? to understand when this might be preferred to simply giving it the same string.
your object should probably implement the copy itself:
#implementation MyData
-(id)copyWithZone:(NSZone *)zone
{
MyData *obj = [[[self class] alloc] init];
obj.uID = self.uId;
obj.name = self.name
...
return obj;
}
....
#end
Change your #property's to use copy instead of retain:
#property (nonatomic) int uID;
#property (nonatomic, copy) NSString *name;
#property (nonatomic, copy) NSString *surname;
#property (nonatomic, copy) NSString *email;
#property (nonatomic, copy) NSString *telephone;
#property (nonatomic, copy) UIImage *image;
Note that you also don't need the assign for the uID. Just leave that part out. Then you can easily create a copy by alloc and init-ing a second MyData object and assigning the properties :
MyData data = [[MyData alloc] init];
newData.surname = data.surname;
newData.email = data.email;
newData.telephone = data.telephone;