MKAnnotation constructor error - iphone

I'm having a problem with MKAnnotation, i created a class "cgdMapAnnotation" for annotations and one of it's constructor is like this:
+ (id) initWithCoordinate:(CLLocationCoordinate2D)coordinate andTitle:(NSString*) title andSubtitle:(NSString*) subtitle {
self = [super alloc];
_coordinate = coordinate;
_title = [title retain];
_subtitle = [subtitle retain];
return self;
}
The problem is that when i call:
cgdMapAnnotation *placemark=[[[cgdMapAnnotation alloc] initWithCoordinate:centerCoordinate andTitle:#"Title" andSubtitle:#"SubTitle" ] autorelease];
I get in the console the following error:
-[cgdMapAnnotation initWithCoordinate:andTitle:andSubtitle:]: unrecognized selector sent to instance 0x33cf2fe0
I really don't understand what's the problem. Can someone help?
Thanks in advance.

First, convention has it that class names start with a capital letter. So cgdMapAnnotation should be CgdMapAnnotation or CGDMapAnnotation.
Second, there are a few problems with initWithCoordinate:andTitle:andSubtitle:.
It is declared as a class method using the '+' at the beginning of the name, but you are attempting to use it as an instance method. [cgdMapAnnotation alloc] will return an instance of cgdMapAnnotation. So you are
self = [super alloc] does not make sense in this class method.
Your method should probably look like this:
- (id)initWithCoordinate:(CLLocationCoodinate2D)coordinate andTitle:(NSString*) title andSubtitle:(NSString*) subtitle
{
if( self = [super init] )
{
_coordinate = coordinate;
_title = [title retain];
_subtitle = [subtitle retain];
}
return self;
}

Related

Adding custom defined objects to NSMutableArray overwrite the whole array

-(id) initWithData:(NSString *)lastName: (NSString *)firstName{
self->firstname = firstName;
self->lastname = lastName;
return self;
}
-(void) printData {
NSLog(#"firstname: %#", firstname);
NSLog(#"lastname: %#", lastname);
}
so whenever I create a new object using the above init function. And Add objects to a NSMutableArray, using the addObject function.
NSMutableArray *objectArray = [[NSMutableArray alloc] init];
CustomObject *tempObject = [[CustomObject alloc] initWithData: #"smith": #"john"];
CustomObject *tempObjectb = [[CustomObject alloc] initWithData: #"brown": #"william"];
[objectArray addObject:tempObject];
[objectArray addObject:tempObjectb];
[[objectArray objectAtIndex:0] printData];
[[objectArray objectAtIndex:1] printData];
objects at index 1, and 0 always equal the whichever object was added to the array last.
This also happens if I use a for loop, or have more than 2 objects, all values when printed, turn to the values of the last added object to the objectArray. Let me know if there is any information that I am missing.
Is there something that I am missing?
Fix your initWithData:lastName: implementation as following:
-(id) initWithData:(NSString *)lastName: (NSString *)firstName
{
self = [super init];
if ( nil != self ) {
self->firstname = [firstName retain];
self->lastname = [lastName retain];
}
return self;
}

iOS - Objects being released?

I have the following piece of code:
Dummy *dummy = [[Dymmy alloc] initWithDictionary:dummyData];
DummyTableItem *dummyTableItem = [DummyTableItem itemWithDummy: dummy];
[_data addObject: dummyTableItem];
The init functions are as follows:
+ (id) itemWithDummy: (Dummy *) dummy {
DummyTableItem *item = [[[self alloc] init] autorelease];
item.dummy = dummy;
return item;
}
- (id) init {
self = [super init];
if( self ) {
dummy = nil;
}
return self;
}
with dummy declared as (nonatomic, retain)
And Dummy:
#synthesize name=_name;
- (id) initWithDictionary: (NSDictionary *) dictionary {
self = [super init];
if( self != nil ) {
if( [dictionary objectForKey:#"name"] )
_name = [dictionary objectForKey:#"name"];
}
return self;
}
with name again declared as (nonatomic, retain)
When I am trying to access later on the dummyTableItem.dummy.name to set it to a UILabel I am getting a "-[CFString isEqualToString:]: message sent to deallocated instance 0x5b37a10"
Am I doing something completely wrong with the retained objects? What am I missing here? Also in the first part of code should I release the dummyTableItem after adding it to _data (which is an NSMutableArray?)
This should solve the problem inside Dummy's #implementation :
#synthesize name=_name;
- (id) initWithDictionary: (NSDictionary *) dictionary {
self = [super init];
if (self) {
_name = [[dictionary objectForKey:#"name"] retain]; //retain it :)
}
return self;
}
Since you declared name as retain you should own it (That is why I added retain when assigning it).
Furthermore, you don't need to check if( [dictionary objectForKey:#"name"] ) because _name = [nil retain]; is nil anyways :)

Why DON'T we use the property in initializer methods? Use the instance variable

Why DON'T we use the property in initializer methods and to Use the instance variable?
init {
self = [super init];
if (self) {
self.someString = [[[NSString alloc] initWithFormat:#"%# %#",#”Mike”, #”Jones”] autorelease];
}
return self;
}
vs:
init {
self = [super init];
if (self) {
_someString = [[[NSString alloc] initWithFormat:#"%# %#",#”Mike”, #”Jones”] autorelease];
}
return self;
}
The correct way is to do
_someString = [[NSString alloc] initWithFormat:#"%# %#",#”Mike”, #”Jones”];
without the autorelease. I assume your property to be retain or (better) copy.
You don't want to call methods in init and dealloc, as they can easily have side effects, either here (now or later) or in a subclass.

release or not release

I'm developing an iPhone application.
I have the following property:
#property (nonatomic, retain) Point2D* endPoint;
And this is a method on the same class:
- (id)initWithX:(CGFloat)x Y:(CGFloat)y;
{
if (self = [super init])
{
endPoint = [[Point2D alloc] initWithX:x Y:y];
...
}
And finally the dealloc method on the same class:
- (void)dealloc {
[endPoint release];
[super dealloc];
}
My question is it this code correct?
endPoint = [[Point2D alloc] initWithX:x Y:y];
Or maybe I have to do an autorelease here.
Go read the memory management guide as it'll explain all of this and a lot more.
In short, that code is correct.
If you did self.endPoint = [... alloc/init ...], then you'd need to autorelease or release in init to balance the extra retain.
Your assignment
endPoint = [[Point2D alloc] initWithX:x Y:y];
does not increase the retainCount, so if you want to keep endPoint to use later you don't use autorelease here.
Or you can use like this
self.endPoint = [[[Point2D alloc] initWithX:x Y:y] autorelease];
=> This assignment will increase the counter of endPoint.
You shouldn't use endPoint directly but rather through self.endPoint.
#property (nonatomic, retain) Point2D* endPoint;
- (id)initWithX:(CGFloat)x Y:(CGFloat)y;
{
if (self = [super init])
{
self.endPoint = [[[Point2D alloc] initWithX:x Y:y] autorelease]; //It'll retain it for us.
...
}
- (void)dealloc {
self.endPoint = nil; //setting it to nil means it'll release the object it was previously pointing to.
[super dealloc];
}
change endPoint = [[Point2D alloc] initWithX:x Y:y]; to
Point2D *temp = [[Point2D alloc] initWithX:x Y:y];
self.endPoint = temp;
[temp release];
to take advantage of the properties retaining setter.

IPhone Repository for data

I'm a totally noob in IPhone development. Just start a week ago. I'm trying to have this tableview working.
I have a class I created called CustomerRepository with a method like this
- (CustomerRepository *) init {
self = [super init];
if (self) {
customerArray = [[NSMutableArray alloc] init];
Customer *cust1 = [[Customer alloc] init];
cust1.name = #"cust1";
[customerArray addObject: cust1];
[cust1 release];
}
return self;
}
- (NSMutableArray *) GetAll {
NSMutableArray *returnCustomerArray = [[[NSMutableArray alloc] init] autorelease];
for(Customer *cust in customerArray)
{
Customer *copy = [[Customer alloc]init];
copy.name = cust.name;
[returnCustomerArray addObject:copy];
[copy release];
}
return returnCustomerArray;
}
Now In my Controller
#synthezise customerArray;
viewDidLoad {
CustomerRepository *custRepo = [[CustomerRepository alloc] init];
customerArray = [custRepo GetAll];
[custRepo release];
}
- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section {
// It always throw an exception here about -[UITableViewRowData count]: unrecognized selector sent to instance
return [customerArray count];
}
There is definitely something wrong with my code, can you guys help me point out what is wrong. Most probably an access to an instance that is already release ....
You need to retain the array returned by GetAll. Try this:
viewDidLoad {
CustomerRepository *custRepo = [[CustomerRepository alloc] init];
customerArray = [[custRepo GetAll] retain];
[custRepo release];
}
If you don't retain it, then your autorelease in -GetAll means that the returned array will eventually be released. When your -numberOfRowsInSection method fires, it's talking to a dealloc'd instance.