Reputation: 48599
In MyModel.h, I declared a delegate variable like this:
@property(weak) IBOutlet id <MyProtocol> delegate;
I've also seen a delegate variable declared like this:
@property(weak) IBOutlet NSObject <MyProtocol>* delegate;
I'm wondering which I should use.
Also, Xcode 6.2 indicates I'm doing something wrong because when I connect the delegate outlet in IB, Xcode still shows an empty circle to the left of the declaration instead of a filled in circle. This is what I did:
1) In IB, I dragged on Object out of the Library onto the dock, and I changed its class to: MyModel.
2) In IB, I dragged another Object onto the dock, and I changed its class to: MyController. I declared the MyController class like this:
@interface MyController : NSObject <MyProtocol>
@property(strong) IBOutlet MyModel* model;
@end
3) In IB, I hooked up the delegate outlet for the MyModel Object to the MyController Object.
But in Xcode, it still shows an empty circle to the left of the line:
@property(weak) IBOutlet id <MyProtocol> delegate;
In other words, Xcode is saying the outlet is not connected to anything--yet my app is able to communicate with the controller using the delegate property.
If I delete <MyProtocol>
from that line, the circle to the left of the line fills in, i.e. Xcode is saying the outlet is now connected to something. Is that an Xcode bug?
Here are the files for my HelloDelegate app:
MyProtocol.h:
//
// MyProtocol.h
// HelloDelegate
//
@class MyModel; //#import "MyModel.h" doesn't work for some reason
@protocol MyProtocol
-(void)sayHello:(MyModel*)model;
@end
MyModel.h:
//
// MyModel.h
// HelloDelegate
//
#import <Foundation/Foundation.h>
#import "MyController.h"
@interface MyModel : NSObject
@property NSString* name;
-(id)initWithName:(NSString*)name;
-(void)doStuff;
@end
MyModel.m:
//
// MyModel.m
// HelloDelegate
//
#import "MyModel.h"
@interface MyModel()
@property(weak) IBOutlet id <MyProtocol> delegate;
@end
@implementation MyModel
-(void)doStuff {
[[self delegate] sayHello:self];
}
-(id) init {
return [self initWithName:@"world"];
}
//Designated initializer:
-(id) initWithName:(NSString *)name {
if (self = [super init]) {
[self setName:name];
}
return self;
}
@end
MyController.h:
//
// MyController.h
// HelloDelegate
//
#import <Foundation/Foundation.h>
#import "MyProtocol.h"
@interface MyController : NSObject <MyProtocol>
@property(strong) IBOutlet MyModel* model;
@end
MyController.m:
//
// MyController.m
// HelloDelegate
//
#import "MyController.h"
#import "MyModel.h"
#import <Cocoa/Cocoa.h>
@interface MyController()
@property(weak) IBOutlet NSTextField* label;
@end
@implementation MyController
-(void)sayHello:(MyModel*)model {
NSString* labelText = [NSString stringWithFormat:@"Hello, %@!", [model name]];
[[self label] setStringValue:labelText];
}
@end
AppDelegate.m:
//
// AppDelegate.m
// HelloDelegate
//
#import "AppDelegate.h"
#import "MyController.h"
#import "MyModel.h"
@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;
@property (strong) IBOutlet MyController* controller;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
[[[self controller] model] doStuff];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
@end
Upvotes: 0
Views: 127
Reputation: 534950
The main difference comes along when you type something as id <SomeProtocol>
and then try to send it a message such as respondsToSelector:
and the compiler won't let you. It comes as a surprise - or at least it sure came as a surprise to me - that id <SomeProtocol>
is not a form of id
. The only messages you can send to such a beast without casting are those defined in the protocol. That's in stark contrast to id
plain and simple, which can be sent any known message.
Thus, in my view, as in that of those who know better than I, NSObject <SomeProtocol>*
is better, because now this thing is seen by the compiler as an NSObject, and can be sent all the messages declared for NSObject.
Upvotes: 1