user489041
user489041

Reputation: 28294

id pointer in Objective-C

I am new to Objective-C. I am coming from a Java background. I am trying to create a generic function in objective-c as follows:

- (id<BaseEntity>*)retreive:(NSString *)idValue unpackedWith:(id<ITransferObject>*) transferObject{
    NSString * url = [[[self baseUurl] stringByAppendingString: [self getPath]]stringByAppendingString: @"/retreive/"];
    url = [url stringByAppendingString:idValue];
    NSMutableURLRequest *request = [self createGET:url];
    NSString *responseString = [self processRequest:request];
    BaseEntity* responseEntity = [transferObject unpack:responseString];
    return responseEntity;
}

What I am trying to accomplish is create a function that can take a pointer to any object that implements the ITransferObject protocol. Use a function on this object as defined in the ITransferObject protocol. Then return a pointer to an object that implements the BaseEntity protocol. I feel like I took a Java generics approach to this and it is not working.

I get the following error:

Bad receiver type `__autoreleasing id<ITransferObject> *'

from this line:

BaseEntity* responseEntity = [transferObject unpack:responseString];

And I get the error:

Implicit conversion of an Objective-C pointer to `__autoreleasing id<BaseEntity> *' is disallowed with ARC

from this line:

return responseEntity;

Any ideas?

Upvotes: 3

Views: 1831

Answers (3)

rob mayoff
rob mayoff

Reputation: 385540

First of all, it looks like BaseEntity is a class, not a protocol, so you can't use it as a protocol.

Second, the id type is inherently a pointer, so you normally don't want to declare a pointer-to-id.

Declare your method like this instead:

- (BaseEntity *)retreive:(NSString *)idValue unpackedWith:(id<ITransferObject>) transferObject{

(Note that I have changed the transferObject type by removing the *.)

Alternatively, use NSObject instead of id and leave the star, this:

- (BaseEntity*)retreive:(NSString *)idValue unpackedWith:(NSObject<ITransferObject>*) transferObject{

Also, the correct spelling is retrieve.

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726499

id is a special type - it is a by-reference type that does not require an asterisk: it is already a pointer. Here is an example that illustrates this point:

-(void)someMethod:(id)data; // id does not need an asterisk
...
NSString *str = @"Hello";   // NSString needs an asterisk
[self someMethod:str];      // This works

Adding an asterisk after an id makes the type a pointer to an id - i.e. a double pointer. There are legitimate situations when you need a pointer to an id, but it is not what you need in your situation.

You have two ways of fixing this issue:

  • You can change id for NSObject (similar to passing Object in Java), or
  • Remove the asterisk after the id.

The second approach is more common:

- (id<BaseEntity>)retreive:(NSString *)idValue unpackedWith:(id<ITransferObject>) transferObject;

Upvotes: 1

Noah Witherspoon
Noah Witherspoon

Reputation: 57149

id is a pointer type in itself—you don’t need to append a * to it to represent a pointer as you do with a class.

- (id<BaseEntity>)retrieve:(NSString *)idValue unpackedWith:(id<ITransferObject>)transferObject

Upvotes: 5

Related Questions