views:

89

answers:

2

Hi, everyone.

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?

+6  A: 

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
+1  A: 

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.

http://stackoverflow.com/questions/918698/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

ahmet emrah
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
hmm so whenever someone uses uitableviews they get errors at run time. i see now. please seehttp://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html
ahmet emrah
please also look at my final edit above
ahmet emrah
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
a delegate is a symbolic common name used for structures like this:@protocol Shield ...@endthe OP tries to release its delegate(i.e shield), and its just wrong for the aforementioned reasons.
ahmet emrah