copy one NSString to another - iphone

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;

Related

iOS - "This class is not key value coding-compliant" when using associations?

I have the following classes declared in my iOS application...
#interface UserRegistrationRequest : BaseServiceRequest
#property (nonatomic, retain) NSString *username;
#property (nonatomic, retain) NSString *password;
#property (nonatomic, retain) NSString *secretQuestionID;
#property (nonatomic, retain) NSString *secretQuestionAnswer;
#property (nonatomic, retain) UserProfile *profile;
#end
#interface UserProfile : NSObject
#property (nonatomic, retain) NSString *emailAddress;
#property (nonatomic, retain) NSString *firstName;
#property (nonatomic, retain) NSString *lastName;
#property (nonatomic, retain) NSData *profileImage;
#property (nonatomic, retain) NSNumber *dateOfBirth;
#end
As best as I can tell, these classes should be key-value coding compliant. However, when I run the following code...
NSString *propKey = #"profile.firstName";
NSString *propVal = [self.registrationRequest valueForKey:propKey];
I get an exception saying...
[<UserRegistrationRequest 0xb6187f0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key profile.firstName.
Any idea why this is happening or what I should be looking for in troubleshooting this?
Use :
NSString *propVal = [self.registrationRequest valueForKeyPath:propKey];

Memory leak in a class with 3 NSMutableArrays. Why?

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.

iOS initializer parameter is nil

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).

How to get house number with MKPlacemark

i can get the street and city by applying this code to the MKReversegeocoder
NSString* city = [placemark.addressDictionary valueForKey:#"City"];
NSString* street = [placemark.addressDictionary valueForKey:#"Street"];
now i am trying to get the street number is it possible?
self.userCoord = [[CLLocation alloc] initWithLatitude:geoPoint.latitude longitude:geoPoint.longitude];
CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:self.userCoord completionHandler:^(NSArray *placemarks, NSError *error)
{
if (error == nil && [placemarks count] > 0)
{
CLPlacemark *placemark = [placemarks lastObject];
self.city.text = placemark.locality;
self.street.text = placemark.thoroughfare;
self.house.text = place mark.subThoroughfare;
}
}
// address dictionary properties
#property (nonatomic, readonly, copy) NSString *name; // eg. Apple Inc.
#property (nonatomic, readonly, copy) NSString *thoroughfare; // street address, eg. 1 Infinite Loop
#property (nonatomic, readonly, copy) NSString *subThoroughfare; // eg. 1
#property (nonatomic, readonly, copy) NSString *locality; // city, eg. Cupertino
#property (nonatomic, readonly, copy) NSString *subLocality; // neighborhood, common name, eg. Mission District
#property (nonatomic, readonly, copy) NSString *administrativeArea; // state, eg. CA
#property (nonatomic, readonly, copy) NSString *subAdministrativeArea; // county, eg. Santa Clara
#property (nonatomic, readonly, copy) NSString *postalCode; // zip code, eg. 95014
#property (nonatomic, readonly, copy) NSString *ISOcountryCode; // eg. US
#property (nonatomic, readonly, copy) NSString *country; // eg. United States
#property (nonatomic, readonly, copy) NSString *inlandWater; // eg. Lake Tahoe
#property (nonatomic, readonly, copy) NSString *ocean; // eg. Pacific Ocean
#property (nonatomic, readonly, copy) NSArray *areasOfInterest; // eg. Golden Gate Park
I think what you're looking for is the subThoroughfare property of MKPlacemark. Note that in iOS 5.0+, subThoroughfare isn't declared on MKPlacemark. It now inherits this from the new superclass, CLPlacemark.

Using a typedef enum in my object Class

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;