1

I've been reading a book about design patterns for Objective-C and many times I've read things like

id <AProtocol> obj;

But I think, in pratice, it's not really usable for a simple reason: in iOS you have to manage memory calling release on the object. If you declate it simple with "id <Protocol>" and you need to release that obj, XCode is going to warn you that the "release" method is not in that protocol.

So a more reallistic approach would be

NSObject <AProtocol> *obj;

Am I right?

Ricardo de Cillo
  • 1,104
  • 9
  • 8

4 Answers4

3

There is also an NSObject protocol, so you can simply define:

@protocol AProtocol <NSObject>

That way the retain, release, etc. methods of NSObject are visible. See also this question.

Community
  • 1
  • 1
DarkDust
  • 90,870
  • 19
  • 190
  • 224
  • You are right. I've just read this from the docs http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html – Ricardo de Cillo Apr 14 '11 at 13:57
2

Unfortunately NSObject <AProtocol> *obj won't compile. But you can tell the compiler that your object conforms to the NSObject protocol. Just declare:

id <NSObject,AProtocol> object;

If you think that's too wordy, you can "import" the NSObject protocol into yours when you define it:

@protocol AProtocol <NSObject>
// ...
@end
odrm
  • 5,149
  • 1
  • 18
  • 13
  • Why wouldn't `NSObject *obj` compile? I've just got it working. That way you'll be using NSObject as an abstract base class. But the two options you pointed out are at the core of the question. The first `` is a more flexible one in the way that I include the NSObject protocol only in the case its going to require the NSObject methods and not wrap it every time as the second option. I think I got it. – Ricardo de Cillo Apr 14 '11 at 14:05
  • Agree, `NSObject *obj` compiles just fine, as does `id obj`. – Caleb Apr 14 '11 at 14:06
  • +1 for the `id object;` declaration. I didn't knew that I can specify several protocols here, and this is a very natural solution. – DarkDust Apr 15 '11 at 07:00
2

You can also make AProtocol itself conform to the NSObject protocol:

@protocol AProtocol <NSObject>
…
@end

By doing that, the compiler won’t emit a warning for:

id <AProtocol> obj;
…
[obj release];
2

Use the most specific one you can. Use NSObject * if you know it is an instance of NSObject and not, say, NSProxy.

Use NSView <AProtocol>* if you know the instance is a subclass of NSView.

However this has nothing to do with -release. If you infact need to protocol to define the release method, that is, it makes no sense for an object to implement this interface if it doesn't also implement the NSObject protocol, include the NSObject protocol in the definition of AProtocol as @Bavarious demonstrates.

hooleyhoop
  • 9,128
  • 5
  • 37
  • 58