1

I have working for iPhone development for a while. First time, I so surprised with memory-management in objective-c :). but now I got it a little bit.

The question is, sometime, I use protocol as an attribute of a class, because I think its definition very similar to 'interface' in C# or Java. like below.

@protocol Shield
   ...
@end

// Interface
@interface Dragon {
    id<Shield> shield
    NSString * name;
}

@property (nonatomic,retain) id<Shield> shield;
@property (nonatomic,retain) NSString * name;

@end

but I alway release any attribute object in dealloc() method. like below.

-(void)dealloc {
   [name release];
   [shield release];  // <--- Totally impossible. xcode said '-release not found in protocol'
   [super dealloc];
 }

As you see, I couldn't release the protocol. So would this cause me future memory issue? Do you have another way to handle this solution to advice me?

Teerasej
  • 1,486
  • 4
  • 21
  • 31
  • iKenndac's answer below is the proper way. Alternatively, you can cast the ID to an NSObject protocol conform ID and call the release method. `[(id – nash Nov 26 '09 at 12:59

2 Answers2

8

You need to define your protocol as adhering to the NSObject protocol, like this:

@protocol Shield <NSObject>
   ...
@end

It's simple when you know how! ;-)

Edit: Also, you're correct - protocols in Objective-C are equivalent to interfaces in Java and C#.

Another edit: It might strike you as odd having to do this, but Objective-C allows for multiple root objects, so you can't actually guarantee that every object will descend from NSObject. Since release is an NSObject method, you have to define your protocol as also adhering to the <NSObject> protocol before you can be sure it'll be able to respond to the release method.

iKenndac
  • 18,730
  • 3
  • 35
  • 51
1

1-the proper thing to do instead of [shield release] is setting

self.shield = nil;

2-Also change

@property (nonatomic,retain) id<Shield> shield; 

to

@property (nonatomic,assign) id<Shield> shield;

Then you are fine.

edit:

The reason that you avoid retaining delegates is that you need to avoid a retain loop:

A creates B A sets itself as B's delegate … A is released by its owner

If B had retained A, A wouldn't be released, as B owns A, thus A's dealloc would never get called, causing both A and B to leak.

You shouldn't worry about A going away b/c it owns B and thus gets rid of it in dealloc.

Why are Objective-C delegates usually given the property assign instead of retain?

please see uitableview class reference for an example protocol declaration:

@property(nonatomic, assign) id < UITableViewDelegate> delegate

Community
  • 1
  • 1
ahmet emrah
  • 1,858
  • 2
  • 15
  • 22
  • There's nothing wrong in releasing member directly. And changing property attribute to assign you either get a memory leak (if shield was retained) or an error at run-time (if you just assign to shield an autoreleased object) – Vladimir Nov 26 '09 at 14:33
  • hmm so whenever someone uses uitableviews they get errors at run time. i see now. please see http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html – ahmet emrah Nov 26 '09 at 15:30
  • OK sorry, I didn't see anything about delegates in original question though. Its hard to talk about attributes without knowing their actual usage – Vladimir Nov 26 '09 at 15:48
  • a delegate is a symbolic common name used for structures like this: @protocol Shield ... @end the OP tries to release its delegate(i.e shield), and its just wrong for the aforementioned reasons. – ahmet emrah Nov 26 '09 at 16:52