From 25fb918e9c0ef62205de86321d503aabf250f60a Mon Sep 17 00:00:00 2001 From: Levi Bostian Date: Wed, 8 Jan 2014 21:27:42 -0600 Subject: Merge with master. --- objective-c.html.markdown | 195 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 4 deletions(-) (limited to 'objective-c.html.markdown') diff --git a/objective-c.html.markdown b/objective-c.html.markdown index 0f0165ec..59169b16 100644 --- a/objective-c.html.markdown +++ b/objective-c.html.markdown @@ -249,14 +249,17 @@ int main (int argc, const char * argv[]) // Your statements here @throw [NSException exceptionWithName:@"FileNotFoundException" reason:@"File Not Found on System" userInfo:nil]; - } @catch (NSException * e) + } @catch (NSException * e) // use: @catch (id exceptionName) to catch all objects. { NSLog(@"Exception: %@", e); } @finally { - NSLog(@"Finally"); + NSLog(@"Finally. Time to clean up."); } // => prints "Exception: File Not Found on System" - // "Finally" + // "Finally. Time to clean up." + + // NSError objects are useful for function arguments to populate on user mistakes. + NSError *error = [NSError errorWithDomain:@"Invalid email." code:4 userInfo:nil]; /////////////////////////////////////// // Objects @@ -549,6 +552,116 @@ int main (int argc, const char * argv[]) { NSLog(@"Car locked."); // Instances of Car can't use lockCar because it's not in the @interface. } +// 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 +// functionality to an object. +// Categories allow you to: +// -- Add methods to an existing class for organizational purposes. +// -- Allow you to extend Objective-C object classes (ex: NSString) to add your own methods. +// -- Add ability to create protected and private methods to classes. +// NOTE: Do not override methods of the base class in a category even though you have the ability +// to. Overriding methods may cause compiler errors later between different categories and it +// ruins the purpose of categories to only ADD functionality. Subclass instead to override methods. + +// Here is a simple Car base class. +@interface Car : NSObject + +@property NSString *make; +@property NSString *color; + +- (void)turnOn; +- (void)accelerate; + +@end + +// And the simple Car base class implementation: +#import "Car.h" + +@implementation Car + +@synthesize make = _make; +@synthesize color = _color; + +- (void)turnOn { + NSLog(@"Car is on."); +} +- (void)accelerate { + NSLog(@"Accelerating."); +} + +@end + +// Now, if we wanted to create a Truck object, we would instead create a subclass of Car as it would +// be changing the functionality of the Car to behave like a truck. But lets say we want to just add +// functionality to this existing Car. A good example would be to clean the car. So we would create +// a category to add these cleaning methods: +// @interface filename: Car+Clean.h (BaseClassName+CategoryName.h) +#import "Car.h" // Make sure to import base class to extend. + +@interface Car (Clean) // The category name is inside () following the name of the base class. + +- (void)washWindows; // Names of the new methods we are adding to our Car object. +- (void)wax; + +@end + +// @implementation filename: Car+Clean.m (BaseClassName+CategoryName.m) +#import "Car+Clean.h" // Import the Clean category's @interface file. + +@implementation Car (Clean) + +- (void)washWindows { + NSLog(@"Windows washed."); +} +- (void)wax { + NSLog(@"Waxed."); +} + +@end + +// Any Car object instance has the ability to use a category. All they need to do is import it: +#import "Car+Clean.h" // Import as many different categories as you want to use. +#import "Car.h" // Also need to import base class to use it's original functionality. + +int main (int argc, const char * argv[]) { + @autoreleasepool { + Car *mustang = [[Car alloc] init]; + mustang.color = @"Red"; + mustang.make = @"Ford"; + + [mustang turnOn]; // Use methods from base Car class. + [mustang washWindows]; // Use methods from Car's Clean category. + } + return 0; +} + +// Objective-C does not have protected method declarations but you can simulate them. +// Create a category containing all of the protected methods, then import it ONLY into the +// @implementation file of a class belonging to the Car class: +@interface Car (Protected) // Naming category 'Protected' to remember methods are protected. + +- (void)lockCar; // Methods listed here may only be created by Car objects. + +@end +//To use protected methods, import the category, then implement the methods: +#import "Car+Protected.h" // Remember, import in the @implementation file only. + +@implementation Car + +- (void)lockCar { + NSLog(@"Car locked."); // Instances of Car can't use lockCar because it's not in the @interface. +} + +@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; @end /////////////////////////////////////// @@ -594,7 +707,7 @@ int main (int argc, const char * argv[]) { // 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 filename: "CarUtilities.h" +// @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. @@ -605,6 +718,7 @@ int main (int argc, const char * argv[]) { @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. +<<<<<<< HEAD @end // The @implementation needs to implement the @properties and methods for the protocol. @implementation Car : NSObject @@ -646,6 +760,49 @@ if ([myClass conformsToProtocol:@protocol(CarUtilities)]) { - (void)beNiceToBrother:(id )brother; +======= +@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; + +>>>>>>> 8c6f583... Add much more to the protocols section. @end // See the problem is that Sister relies on Brother, and Brother relies on Sister. #import "Sister.h" @@ -658,6 +815,36 @@ if ([myClass conformsToProtocol:@protocol(CarUtilities)]) { @end + +/////////////////////////////////////// +// Blocks +/////////////////////////////////////// +// Blocks are statements of code, just like a function, that is able to be used as data. +// Below is a simple block with an integer argument that returns the argument plus 4. +int (^addUp)(int n); // Declare a variable to store the block. +void (^noParameterBlockVar)(void); // Example variable declaration of block with no arguments. +// Blocks have access to variables in the same scope. But the variables are readonly and the +// value passed to the block is the value of the variable when the block is created. +int outsideVar = 17; // If we edit outsideVar after declaring addUp, outsideVar is STILL 17. +__block long mutableVar = 3; // __block makes variables writable to blocks, unlike outsideVar. +addUp = ^(int n) { // Remove (int n) to have a block that doesn't take in any parameters. + NSLog(@"You may have as many lines in a block as you would like."); + NSSet *blockSet; // Also, you can declare local variables. + mutableVar = 32; // Assigning new value to __block variable. + return n + outsideVar; // Return statements are optional. +} +int addUp = add(10 + 16); // Calls block code with arguments. +// Blocks are often used as arguments to functions to be called later, or for callbacks. +@implementation BlockExample : NSObject + + - (void)runBlock:(void (^)(NSString))block { + NSLog(@"Block argument returns nothing and takes in a NSString object."); + block(@"Argument given to block to execute."); // Calling block. + } + + @end + + /////////////////////////////////////// // Memory Management /////////////////////////////////////// -- cgit v1.2.3 From dcf7cd620d9e957d384e143eb2fb2cca7351cfae Mon Sep 17 00:00:00 2001 From: Levi Bostian Date: Fri, 10 Jan 2014 22:58:45 -0600 Subject: Add to exceptions section. Add NSError reference. --- objective-c.html.markdown | 3 --- 1 file changed, 3 deletions(-) (limited to 'objective-c.html.markdown') diff --git a/objective-c.html.markdown b/objective-c.html.markdown index 59169b16..348a72d5 100644 --- a/objective-c.html.markdown +++ b/objective-c.html.markdown @@ -718,7 +718,6 @@ int main (int argc, const char * argv[]) { @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. -<<<<<<< HEAD @end // The @implementation needs to implement the @properties and methods for the protocol. @implementation Car : NSObject @@ -760,7 +759,6 @@ if ([myClass conformsToProtocol:@protocol(CarUtilities)]) { - (void)beNiceToBrother:(id )brother; -======= @end // The @implementation needs to implement the @properties and methods for the protocol. @implementation Car : NSObject @@ -802,7 +800,6 @@ if ([myClass conformsToProtocol:@protocol(CarUtilities)]) { - (void)beNiceToBrother:(id )brother; ->>>>>>> 8c6f583... Add much more to the protocols section. @end // See the problem is that Sister relies on Brother, and Brother relies on Sister. #import "Sister.h" -- cgit v1.2.3 From 58bd9cbdaf97955fab0b6a0ae1f0827f84abdefa Mon Sep 17 00:00:00 2001 From: Levi Bostian Date: Wed, 19 Mar 2014 12:39:07 -0500 Subject: Remove duplicate Categories section. Fix small typo. --- objective-c.html.markdown | 152 +--------------------------------------------- 1 file changed, 1 insertion(+), 151 deletions(-) (limited to 'objective-c.html.markdown') diff --git a/objective-c.html.markdown b/objective-c.html.markdown index 348a72d5..772e72ca 100644 --- a/objective-c.html.markdown +++ b/objective-c.html.markdown @@ -552,116 +552,6 @@ int main (int argc, const char * argv[]) { NSLog(@"Car locked."); // Instances of Car can't use lockCar because it's not in the @interface. } -// 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 -// functionality to an object. -// Categories allow you to: -// -- Add methods to an existing class for organizational purposes. -// -- Allow you to extend Objective-C object classes (ex: NSString) to add your own methods. -// -- Add ability to create protected and private methods to classes. -// NOTE: Do not override methods of the base class in a category even though you have the ability -// to. Overriding methods may cause compiler errors later between different categories and it -// ruins the purpose of categories to only ADD functionality. Subclass instead to override methods. - -// Here is a simple Car base class. -@interface Car : NSObject - -@property NSString *make; -@property NSString *color; - -- (void)turnOn; -- (void)accelerate; - -@end - -// And the simple Car base class implementation: -#import "Car.h" - -@implementation Car - -@synthesize make = _make; -@synthesize color = _color; - -- (void)turnOn { - NSLog(@"Car is on."); -} -- (void)accelerate { - NSLog(@"Accelerating."); -} - -@end - -// Now, if we wanted to create a Truck object, we would instead create a subclass of Car as it would -// be changing the functionality of the Car to behave like a truck. But lets say we want to just add -// functionality to this existing Car. A good example would be to clean the car. So we would create -// a category to add these cleaning methods: -// @interface filename: Car+Clean.h (BaseClassName+CategoryName.h) -#import "Car.h" // Make sure to import base class to extend. - -@interface Car (Clean) // The category name is inside () following the name of the base class. - -- (void)washWindows; // Names of the new methods we are adding to our Car object. -- (void)wax; - -@end - -// @implementation filename: Car+Clean.m (BaseClassName+CategoryName.m) -#import "Car+Clean.h" // Import the Clean category's @interface file. - -@implementation Car (Clean) - -- (void)washWindows { - NSLog(@"Windows washed."); -} -- (void)wax { - NSLog(@"Waxed."); -} - -@end - -// Any Car object instance has the ability to use a category. All they need to do is import it: -#import "Car+Clean.h" // Import as many different categories as you want to use. -#import "Car.h" // Also need to import base class to use it's original functionality. - -int main (int argc, const char * argv[]) { - @autoreleasepool { - Car *mustang = [[Car alloc] init]; - mustang.color = @"Red"; - mustang.make = @"Ford"; - - [mustang turnOn]; // Use methods from base Car class. - [mustang washWindows]; // Use methods from Car's Clean category. - } - return 0; -} - -// Objective-C does not have protected method declarations but you can simulate them. -// Create a category containing all of the protected methods, then import it ONLY into the -// @implementation file of a class belonging to the Car class: -@interface Car (Protected) // Naming category 'Protected' to remember methods are protected. - -- (void)lockCar; // Methods listed here may only be created by Car objects. - -@end -//To use protected methods, import the category, then implement the methods: -#import "Car+Protected.h" // Remember, import in the @implementation file only. - -@implementation Car - -- (void)lockCar { - NSLog(@"Car locked."); // Instances of Car can't use lockCar because it's not in the @interface. -} - -@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; @end /////////////////////////////////////// @@ -760,47 +650,7 @@ if ([myClass conformsToProtocol:@protocol(CarUtilities)]) { - (void)beNiceToBrother:(id )brother; @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" @@ -816,7 +666,7 @@ if ([myClass conformsToProtocol:@protocol(CarUtilities)]) { /////////////////////////////////////// // Blocks /////////////////////////////////////// -// Blocks are statements of code, just like a function, that is able to be used as data. +// Blocks are statements of code, just like a function, that are able to be used as data. // Below is a simple block with an integer argument that returns the argument plus 4. int (^addUp)(int n); // Declare a variable to store the block. void (^noParameterBlockVar)(void); // Example variable declaration of block with no arguments. -- cgit v1.2.3