Cocoa Heads Tricity - Design Patterns

35
Designs, patterns and practices in Object Oriented Programming for iOS Developers

description

 

Transcript of Cocoa Heads Tricity - Design Patterns

Page 1: Cocoa Heads Tricity - Design Patterns

Designs, patterns and practices in Object Oriented Programming

for iOS Developers

Page 3: Cocoa Heads Tricity - Design Patterns

Agenda

• obvious best practices in Obj-C (or at least what I do)

• software design patterns

• In mean time there are some questions waiting for you

Page 4: Cocoa Heads Tricity - Design Patterns

The obvious is that which is never seen until someone

expresses it simply.

Khalil Gibran

Page 5: Cocoa Heads Tricity - Design Patterns

Best Practices

Page 6: Cocoa Heads Tricity - Design Patterns

#pragma mark - group stuff

Page 7: Cocoa Heads Tricity - Design Patterns

CHCamelCaseWordInEnglish

Page 8: Cocoa Heads Tricity - Design Patterns

@properties vs iVars

Page 9: Cocoa Heads Tricity - Design Patterns

NEON for the performance

Page 10: Cocoa Heads Tricity - Design Patterns

Method naming

Page 11: Cocoa Heads Tricity - Design Patterns

Examples

- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;

- (UIView*)taggedView:(NSInteger)tag;

- (void)setT:(NSString *)text i:(UIImage *)image;

- (void)sendAction:(SEL)aSelector: (id)anObject :(BOOL)flag;

Page 12: Cocoa Heads Tricity - Design Patterns

.Notation or [Brackets]

Page 13: Cocoa Heads Tricity - Design Patterns

if (!error) return success;

Page 14: Cocoa Heads Tricity - Design Patterns

Ternary operator

NSInteger value = 5; result = (value != 0) ? x : y;

int a = 1, b = 2, c = 3, d = 4; int x = 10, y = 5; int result = a > b ? x = c > d ? c : d : y;

Page 15: Cocoa Heads Tricity - Design Patterns

Design Patterns

- are reusable solutions to common problems in software design.

!- They’re templates designed to help you write

code that’s easy to understand and reuse. !- They also help you create loosely coupled

code so that you can change or replace components in your code without too much of a hassle.

Page 16: Cocoa Heads Tricity - Design Patterns
Page 17: Cocoa Heads Tricity - Design Patterns

MVC

Page 18: Cocoa Heads Tricity - Design Patterns

KVO

Page 19: Cocoa Heads Tricity - Design Patterns

Singleton

Page 20: Cocoa Heads Tricity - Design Patterns

How to use ?

Page 21: Cocoa Heads Tricity - Design Patterns

Singletons in Obj-C

• [NSUserDefaults standardUserDefaults]

• [UIScreen mainScreen]

• [NSFileManager defaultManager]

• [UIApplication sharedApplication]

Page 22: Cocoa Heads Tricity - Design Patterns
Page 23: Cocoa Heads Tricity - Design Patterns

Façade• make a software library easier to

use, understand and test, since the facade has convenient methods for common tasks;

• make the library more readable, for the same reason;

• reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;

• wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).

Page 24: Cocoa Heads Tricity - Design Patterns
Page 25: Cocoa Heads Tricity - Design Patterns

Strategy

Page 26: Cocoa Heads Tricity - Design Patterns

Strategy

• defines a family of algorithms,

• encapsulates each algorithm

• makes the algorithms interchangeable within that family.

Page 27: Cocoa Heads Tricity - Design Patterns

@protocol Strategy <NSObject> !@optional - (void) execute; !@end

@interface ConcreteStrategyA : NSObject <Strategy> { // ivars for A } @end

@implementation ConcreteStrategyA !- (void) execute { NSLog(@"Called ConcreteStrategyA execute method"); } !@end

Page 28: Cocoa Heads Tricity - Design Patterns

@interface Context : NSObject { id<Strategy> strategy; } @property (assign) id<Strategy> strategy; !- (void) execute; !@end

@implementation Context !@synthesize strategy; !- (void) execute { if ([strategy respondsToSelector:@selector(execute)]) { [strategy execute]; } } !@end

Page 29: Cocoa Heads Tricity - Design Patterns

Decorator (Wrapper, Adapter)

is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.

Page 30: Cocoa Heads Tricity - Design Patterns

Category#import "UIImage+Retina4.h" #import <objc/runtime.h> !static Method origImageNamedMethod = nil; !@implementation UIImage (Retina4) !+ (void)initialize { origImageNamedMethod = class_getClassMethod(self, @selector(imageNamed:)); method_exchangeImplementations(origImageNamedMethod, class_getClassMethod(self, @selector(retina4ImageNamed:))); } !+ (UIImage *)retina4ImageNamed:(NSString *)imageName { NSMutableString *imageNameMutable = [imageName mutableCopy]; NSRange retinaAtSymbol = [imageName rangeOfString:@"@"]; if (retinaAtSymbol.location != NSNotFound) { [imageNameMutable insertString:@"-568h" atIndex:retinaAtSymbol.location]; } else { CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; if ([UIScreen mainScreen].scale == 2.f && screenHeight == 568.0f) { NSRange dot = [imageName rangeOfString:@"."]; if (dot.location != NSNotFound) { [imageNameMutable insertString:@"-568h@2x" atIndex:dot.location]; } else { [imageNameMutable appendString:@"-568h@2x"]; } } } NSString *imagePath = [[NSBundle mainBundle] pathForResource:imageNameMutable ofType:@""]; if (imagePath) { return [UIImage retina4ImageNamed:imageNameMutable]; } else { return [UIImage retina4ImageNamed:imageName]; } return nil; } !@end

Page 31: Cocoa Heads Tricity - Design Patterns

DelegateThis is an important pattern. Apple uses this approach in most of the UIKit classes:

UITableViewUITextView

UITextField

UIWebView

UIAlertUIActionSheet

UICollectionView

UIGestureRecognizer

UIScrollView

UIPickerView

Page 32: Cocoa Heads Tricity - Design Patterns

Commandis a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time

Page 33: Cocoa Heads Tricity - Design Patterns

NSInvocation

!NSMethodSignature * mySignature = [NSMutableArray instanceMethodSignatureForSelector:@selector(addObject:)]; NSInvocation * myInvocation = [NSInvocation invocationWithMethodSignature:mySignature]; NSString * myString = @"String"; //Next, you would specify which object to send the message to: ![myInvocation setTarget:myArray]; //Specify the message you wish to send to that object: ![myInvocation setSelector:@selector(addObject:)]; //And fill in any arguments for that method: ![myInvocation setArgument:&myString atIndex:2]; //Note that object arguments must be passed by pointer. !//At this point, myInvocation is a complete object, describing a message that can be sent. To actually send the message, you would call: ![myInvocation invoke];

An NSInvocation is an Objective-C message rendered static, that is, it is an action turned into an object.

!

Page 34: Cocoa Heads Tricity - Design Patterns

Where to go from that?

Page 35: Cocoa Heads Tricity - Design Patterns

Thank you for your attention!Questions?