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];
Related
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 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.
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;
I have a couple of properties declared in my header file, and just wondering when they have to be released. I'm currently doing them in my "dealloc" method, but getting the EXC_BAD_ACCESS error when doing so.
Here's my code
#property (nonatomic, retain) NSTimer *timer;
#property (nonatomic, retain) NSString *closeimage;
#property (nonatomic, retain) NSString *alertStyle;
#property (nonatomic, retain) NSString *phonelaunch;
#property (nonatomic, retain) NSString *resultmessage;
Here's my dealloc method
- (void)dealloc {
[super dealloc];
[timer release];
[closeimage release];
[alertStyle release];
[phonelaunch release];
[resultmessage release];
}
Thanks for any help in advance!
Put your [super dealloc] message at the end of your dealloc method.