From 718c2289e54fb707e49ca373b8083d7e85bf8dde Mon Sep 17 00:00:00 2001 From: Levi Bostian Date: Thu, 9 Jan 2014 19:56:23 -0600 Subject: [PATCH] Add much more to the protocols section. --- objective-c.html.markdown | 70 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/objective-c.html.markdown b/objective-c.html.markdown index 47af5ae8..9e41e135 100644 --- a/objective-c.html.markdown +++ b/objective-c.html.markdown @@ -449,7 +449,9 @@ distance = 18; // References "long distance" from MyClass implementation @end // States the end of the implementation +/////////////////////////////////////// // Categories +/////////////////////////////////////// // A category is a group of methods designed to extend a class. They allow you to add new methods // to an existing class for organizational purposes. This is not to be mistaken with subclasses. // Subclasses are meant to CHANGE functionality of an object while categories instead ADD @@ -553,7 +555,9 @@ int main (int argc, const char * argv[]) { @end +/////////////////////////////////////// // Extensions +/////////////////////////////////////// // Extensions allow you to override public access property attributes and methods of an @interface. // @interface filename: Shape.h @interface Shape : NSObject // Base Shape class extension overrides below. @@ -588,15 +592,75 @@ int main (int argc, const char * argv[]) { @end - +/////////////////////////////////////// // Protocols +/////////////////////////////////////// // A protocol declares methods that can be implemented by any class. // Protocols are not classes themselves. They simply define an interface // that other objects are responsible for implementing. -@protocol MyProtocol - - (void)myProtocolMethod; + // @protocol filename: "CarUtilities.h" +@protocol CarUtilities // => Name of another protocol this protocol includes. + @property BOOL engineOn; // Adopting class must @synthesize all defined @properties and + - (void)turnOnEngine; // all defined methods. @end +// Below is an example class implementing the protocol. +#import "CarUtilities.h" // Import the @protocol file. +@interface Car : NSObject // Name of protocol goes inside <> + // You don't need the @property or method names here for CarUtilities. Only @implementation does. +- (void)turnOnEngineWithUtilities:(id )car; // You can use protocols as data too. +@end +// The @implementation needs to implement the @properties and methods for the protocol. +@implementation Car : NSObject + +@synthesize engineOn = _engineOn; // Create a @synthesize statement for the engineOn @property. + +- (void)turnOnEngine { // Implement turnOnEngine however you would like. Protocols do not define + _engineOn = YES; // how you implement a method, it just requires that you do implement it. +} +// You may use a protocol as data as you know what methods and variables it has implemented. +- (void)turnOnEngineWithCarUtilities:(id )objectOfSomeKind { + [objectOfSomeKind engineOn]; // You have access to object variables + [objectOfSomeKind turnOnEngine]; // and the methods inside. + [objectOfSomeKind engineOn]; // May or may not be YES. Class implements it however it wants. +} + +@end +// Instances of Car now have access to the protocol. +Car *carInstance = [[Car alloc] init]; +[[carInstance setEngineOn:NO]; +[carInstance turnOnEngine]; +if ([carInstance engineOn]) { + NSLog(@"Car engine is on."); // prints => "Car engine is on." +} +// Make sure to check if an object of type 'id' implements a protocol before calling protocol methods: +if ([myClass conformsToProtocol:@protocol(CarUtilities)]) { + NSLog(@"This does not run as the MyClass class does not implement the CarUtilities protocol."); +} else if ([carInstance conformsToProtocol:@protocol(CarUtilities)]) { + NSLog(@"This does run as the Car class implements the CarUtilities protocol."); +} +// Categories may implement protocols as well: @interface Car (CarCategory) +// You may implement many protocols: @interface Car : NSObject +// NOTE: If two or more protocols rely on each other, make sure to forward-declare them: +#import "Brother.h" + +@protocol Brother; // Forward-declare statement. Without it, compiler would through error. + +@protocol Sister + +- (void)beNiceToBrother:(id )brother; + +@end +// See the problem is that Sister relies on Brother, and Brother relies on Sister. +#import "Sister.h" + +@protocol Sister; // These lines stop the recursion, resolving the issue. + +@protocol Brother + +- (void)beNiceToSister:(id )sister; + +@end /////////////////////////////////////// // Memory Management