Objective-C - IEEE UNIPV Student Branchieee.unipv.it/documents/Objective_C.pdf• Objective-C 2.0...
Transcript of Objective-C - IEEE UNIPV Student Branchieee.unipv.it/documents/Objective_C.pdf• Objective-C 2.0...
Giuseppe Arici § iOS Bootcamp
Objective-CThe Apple Programming Language
iOS Bootcamp
History
iOS Bootcamp
Once upon a time …
Bells / Xerox / Apple / Xerox / ITT / StepStone / NeXT / Cern / Sun / Apple
1979
1976
1972
1970
1988
1985
1984
1980
1997
1996
1993
1991
2008
2007
2005
2001
iOS Bootcamp
Language
iOS Bootcamp
A strict superset of C
@@"" @( ) @[ ] @{ } @catch @class @defs @dynamic @encode @end @finally @implementation @interface @optional
@private @property @protected @protocol @public @required @selector @synchronized @synthesize @throw @try
SEL IMP nil Nil
BOOL YES NO id typ
edef
self super
hidde
n par
amete
rsin out inout bycopy
byref oneway getter setter
readwrite readonly assign retain
copy nonatomic strong weak av
ailab
le in
parti
cular
cont
exts
iOS Bootcamp
*, &, [ ]
Objective-C
function
Struct
void, char, int, long, float
for, do, whileif, else, switch, case
typedef, enum, union
c "string"
const, auto, static, extern
member selection . ->
# preprocessor
c {array}
C Standard Library
sizeof
(type)casting
break, continue, goto
signed, unsigned
function pointer
malloc, free
format specifiers %d %s stack vs heap
int main(int argc, const char * argv[])
iOS Bootcamp
Inheritance
Objective-C
MethodClass
Polymorphism
Abstraction
Encapsulation
Message passing
Instance VariableDelegation
SuperclassMethod overriding
Subclass
Dynamic dispatch / binding
Interface / Protocol
iOS Bootcamp
Class
iOS Bootcamp
Class
@implementation
// Person.m !#import "Person.h" !@implementation Person !@end
#import
@interface
// Person.h !!!@interface Person : NSObject !@end
iOS Bootcamp
Class @interface
iOS Bootcamp
Class @interface
#import <Foundation/Foundation.h> !@interface BankAccount : NSObject { NSInteger _balance; } !- (NSInteger) withdraw:(NSInteger)amount; - (void) deposit:(NSInteger)amount; !@end
iOS Bootcamp
Class @interface
#import <Foundation/Foundation.h> !@interface BankAccount : NSObject { NSInteger _balance; } !- (NSInteger) withdraw:(NSInteger)amount; - (void) deposit:(NSInteger)amount; !@end
base types import
iOS Bootcamp
Class @interface
#import <Foundation/Foundation.h> !@interface BankAccount : NSObject { NSInteger _balance; } !- (NSInteger) withdraw:(NSInteger)amount; - (void) deposit:(NSInteger)amount; !@end
class definition start
iOS Bootcamp
Class @interface
#import <Foundation/Foundation.h> !@interface BankAccount : NSObject { NSInteger _balance; } !- (NSInteger) withdraw:(NSInteger)amount; - (void) deposit:(NSInteger)amount; !@end
class name
iOS Bootcamp
Class @interface
#import <Foundation/Foundation.h> !@interface BankAccount : NSObject { NSInteger _balance; } !- (NSInteger) withdraw:(NSInteger)amount; - (void) deposit:(NSInteger)amount; !@end
parent class
extends
iOS Bootcamp
Class @interface
#import <Foundation/Foundation.h> !@interface BankAccount : NSObject { NSInteger _balance; } !- (NSInteger) withdraw:(NSInteger)amount; - (void) deposit:(NSInteger)amount; !@end
instance variables
iOS Bootcamp
Class @interface
#import <Foundation/Foundation.h> !@interface BankAccount : NSObject { NSInteger _balance; } !- (NSInteger) withdraw:(NSInteger)amount; - (void) deposit:(NSInteger)amount; !@end
methods declarations
iOS Bootcamp
Class @interface
#import <Foundation/Foundation.h> !@interface BankAccount : NSObject { NSInteger _balance; } !- (NSInteger) withdraw:(NSInteger)amount; - (void) deposit:(NSInteger)amount; !@end
class definition end
iOS Bootcamp
Class @interface
#import <Foundation/Foundation.h> !@interface BankAccount : NSObject { NSInteger _balance; } !- (NSInteger) withdraw:(NSInteger)amount; - (void) deposit:(NSInteger)amount; !@end
iOS Bootcamp
Class @implementation
!!
iOS Bootcamp
Class @implementation
#import "BankAccount.h" !@implementation BankAccount !- (id) init { self = [super init]; return self; } !- (NSInteger) withdraw:(NSInteger)amount { return amount; } !- (void) deposit:(NSInteger)amount { _balance += amount; } @end
iOS Bootcamp
Class @implementation
#import "BankAccount.h" !@implementation BankAccount !- (id) init { self = [super init]; return self; } !- (NSInteger) withdraw:(NSInteger)amount { return amount; } !- (void) deposit:(NSInteger)amount { _balance += amount; } @end
interface import
iOS Bootcamp
Class @implementation
#import "BankAccount.h" !@implementation BankAccount !- (id) init { self = [super init]; return self; } !- (NSInteger) withdraw:(NSInteger)amount { return amount; } !- (void) deposit:(NSInteger)amount { _balance += amount; } @end
class implementation start
iOS Bootcamp
Class @implementation
#import "BankAccount.h" !@implementation BankAccount !- (id) init { self = [super init]; return self; } !- (NSInteger) withdraw:(NSInteger)amount { return amount; } !- (void) deposit:(NSInteger)amount { _balance += amount; } @end
methods with bodies
iOS Bootcamp
Class @implementation
#import "BankAccount.h" !@implementation BankAccount !- (id) init { self = [super init]; return self; } !- (NSInteger) withdraw:(NSInteger)amount { return amount; } !- (void) deposit:(NSInteger)amount { _balance += amount; } @end
class implementation end
iOS Bootcamp
Class @implementation
#import "BankAccount.h" !@implementation BankAccount !- (id) init { self = [super init]; return self; } !- (NSInteger) withdraw:(NSInteger)amount { return amount; } !- (void) deposit:(NSInteger)amount { _balance += amount; } @end
iOS Bootcamp
Instance Variable Declaration
@interface MyClass : NSObject { !!!!!!!!!!!!!!!!!!! }
iOS Bootcamp
Instance Variable Declaration
@interface MyClass : NSObject { @private // Can only be accessed by instances of MyClass NSInteger _privateIvar1; NSString *_privateIvar2; !!!!!!!!!!!!!! }
iOS Bootcamp
Instance Variable Declaration
@interface MyClass : NSObject { @private // Can only be accessed by instances of MyClass NSInteger _privateIvar1; NSString *_privateIvar2; @protected // Default // Can only be accessed by instances of MyClass or MyClass's subclasses NSInteger _protectedIvar1; NSString *_protectedIvar2; !!!!!!!!!!!}
iOS Bootcamp
Instance Variable Declaration
@interface MyClass : NSObject { @private // Can only be accessed by instances of MyClass NSInteger _privateIvar1; NSString *_privateIvar2; @protected // Default // Can only be accessed by instances of MyClass or MyClass's subclasses NSInteger _protectedIvar1; NSString *_protectedIvar2; ! @package // 64-bit only // Can be accessed by any object in the framework in which MyClass is defined NSInteger _packageIvar1; NSString *_packageIvar2; !!!! }
iOS Bootcamp
Instance Variable Declaration
@interface MyClass : NSObject { @private // Can only be accessed by instances of MyClass NSInteger _privateIvar1; NSString *_privateIvar2; @protected // Default // Can only be accessed by instances of MyClass or MyClass's subclasses NSInteger _protectedIvar1; NSString *_protectedIvar2; ! @package // 64-bit only // Can be accessed by any object in the framework in which MyClass is defined NSInteger _packageIvar1; NSString *_packageIvar2; @public // Never use it ! // Can be accessed by any object NSInteger _publicVar1; NSString *_publicVar2; }
iOS Bootcamp
Bad News
NO namespaces ☹ Use prefix instead !
NSObject, NSString, ... !UIButton, UILabel, ... !ABAddressBook, ABRecord, ... !// Pragma Mark PMDeveloper, PMEvent, ...
Draft Proposal for Namespaces in Objective-C: @namespace @using http://www.optshiftk.com/2012/04/draft-proposal-for-namespaces-in-objective-c/
iOS Bootcamp
Method & Message
iOS Bootcamp
Method Declaration
- (BOOL) writeToFile:(NSString *)path atomically:(BOOL)flag;
iOS Bootcamp
Method Declaration
- (BOOL) writeToFile:(NSString *)path atomically:(BOOL)flag;
method scope
Can be either:
+ for a class method
- for an instance method
Methods are always public !
“Private” methods defined in implementation
iOS Bootcamp
Method Declaration
- (BOOL) writeToFile:(NSString *)path atomically:(BOOL)flag;
return type
Can be any valid data type, including:
void returns nothing
id a pointer to an object of any class
NSString * a pointer to an NSString
BOOL a boolean (YES or NO)
iOS Bootcamp
Method Declaration
- (BOOL) writeToFile:(NSString *)path atomically:(BOOL)flag;
method name
The method name is composed of all labels
Colons precede arguments, but are part of the method name
writeTofile:atomically:
iOS Bootcamp
Method Declaration
- (BOOL) writeToFile:(NSString *)path atomically:(BOOL)flag;
argument type
Arguments come after or within the method name
argument name
iOS Bootcamp
[data writeToFile:@"/tmp/data.txt" atomically:YES];
Message Passing
Nested Message Passing:
square brackets syntax
[[store data] writeToFile:[@"/tmp/data.txt" lowercaseString] atomically:[[PMOption sharedOption] writeMode] encoding:NSUTF8StringEncoding error:&error];
[ [ ] [ ] [ [ ] ] ]
iOS Bootcamp
Object Life Cycle
iOS Bootcamp
Memory Management
• Manual Reference Counting
• Higher level abstraction than malloc / free
• Straightforward approach, but must adhere to conventions and rules
• Automatic Reference Counting (ARC)
• Makes memory management the job of the compiler (and runtime)
• Available for: partially iOS 4+ or OS X 10.6+ / fully iOS 5+ or OS X 10.7+
• Garbage Collection
• Only available for OS X 10.5+, but depracated from 10.8+
• Not available on iOS due to performance concerns
iOS Bootcamp
Manual Reference Counting
retain
2
alloc
1
release
1
release
0
(Only) Objective-C objects are reference counted:
• Objects start with retain count of 1 when created
• Increased with retain
• Decreased with [auto]release
• When count equals 0, runtime invokes dealloc
dealloc
iOS Bootcamp
The Memory Management Rule
!
!
Everything that increases the reference count with alloc, copy, new or retain is in charge of
the corresponding [auto]release.
From C++ to Objective-C http://pierre.chachatelier.fr/programmation/objective-c.php
iOS Bootcamp
Automatic Reference Counting
• The Rule is still valid, but it is managed by the compiler
• No more retain, [auto]release nor dealloc
• ARC is used in all new projects by default
• Apple provides a migration tool which is build into Xcode
iOS Bootcamp
Object Construction
• NSObject defines class method called alloc
• NSObject defines instance method called init
• alloc and init calls are always nested into single line
BankAccount *account = [BankAccount alloc];
BankAccount *account = [[BankAccount alloc] init];
[account init];
iOS Bootcamp
Object Destructiondealloc
• Never call explicitly
• Release all retained or copied instance variables (* if not ARC)
• Calls [super dealloc] (* if not ARC)
- (void)saveThis:(id)object { if (_instanceVariable != object ) { [_instanceVariable release]; _instanceVariable = [object retain]; } } !- (void)dealloc { [_instanceVariable release]; [super dealloc]; }
iOS Bootcamp
Property
iOS Bootcamp
Property Access
• Generated properties are standard methods
• Accessed through normal messaging syntax
• Objective-C 2.0 property access via dot syntax
• Dot notation is just syntactic sugar. Still uses accessor methods. Doesn't get/set values directly
id value = [object property]; [object setProperty:newValue];
id value = object.property; object.property = newValue;
iOS Bootcamp
Property Declaration@property(attributes) type name;
Attribute Impacts
readonly / readwrite Mutability
getter / setter API
nonatomic Concurrency
assign / retain / copy weak / strong (* in ARC) Storage
iOS Bootcamp
Property Declaration@property(attributes) type name;
Attribute Impacts
readonly / readwrite Mutability
getter / setter API
nonatomic Concurrency
assign / retain / copy weak / strong (* in ARC) Storage
@property(readonly) NSString *accountNumber;
iOS Bootcamp
Property Declaration@property(attributes) type name;
Attribute Impacts
readonly / readwrite Mutability
getter / setter API
nonatomic Concurrency
assign / retain / copy weak / strong (* in ARC) Storage
@property(getter=isActive) BOOL active;
iOS Bootcamp
Property Declaration@property(attributes) type name;
Attribute Impacts
readonly / readwrite Mutability
getter / setter API
nonatomic Concurrency
assign / retain / copy weak / strong (* in ARC) Storage
@property(nonatomic, retain) NSDate *createdAt;
iOS Bootcamp
Property Declaration@property(attributes) type name;
Attribute Impacts
readonly / readwrite Mutability
getter / setter API
nonatomic Concurrency
assign / retain / copy weak / strong (* in ARC) Storage
@property(readwrite, copy) NSString *accountNumber;
iOS Bootcamp
Property @interface
#import <Foundation/Foundation.h> !@interface BankAccount : NSObject { NSString *_accountNumber; NSDecimalNumber *_balance; NSDecimalNumber *_fees; BOOL _active; } !@property(readwrite, copy) NSString *accountNumber; @property(readwrite, strong) NSDecimalNumber *balance; @property(readonly) NSDecimalNumber *fees; @property(getter=isActive) BOOL active; !@end
iOS Bootcamp
Property @interface
#import <Foundation/Foundation.h> !@interface BankAccount : NSObject { // No more instance variable declarations ! !!!!} !@property(readwrite, copy) NSString *accountNumber; @property(readwrite, strong) NSDecimalNumber *balance; @property(readonly) NSDecimalNumber *fees; @property(getter=isActive) BOOL active; !@end
New in iOS 4+ & OS X 10.6+
iOS Bootcamp
Property @implementation
#import "BankAccount.h" !@implementation BankAccount !//... !@synthesize accountNumber = _accountNumber; @synthesize balance = _balance; @synthesize fees = _fees; @synthesize active = _active; !//... !@end
iOS Bootcamp
Property @implementation
#import "BankAccount.h" !@implementation BankAccount !// No more @synthesize statements ! !!!!!!//... !@end
New in Xcode 4.4+
(WWDC 2012)
iOS Bootcamp
Protocol & Category
iOS Bootcamp
Protocol
• List of method declarations
• Define methods that others are expected to implement
• Conformance can be @required or @optional
Java / C# Interface done Objective-C style
iOS Bootcamp
Protocol
• Defining a Protocol
• Adopting a Protocol
@protocol NSCoding !- (void)encodeWithCoder:(NSCoder *)aCoder; - (id)initWithCoder:(NSCoder *)aDecoder; !@end
@interface Person : NSObject<NSCoding> { !} // method & property declarations @end
iOS Bootcamp
Category
• Add new methods to existing classes
• Does not define new instance variables
• Often used in defining “private” methods
Extending Object Features
iOS Bootcamp
#import "NSString+PMAddition.h" // ... NSString *string = @" A string to be trimmed"; NSLog(@"Trimmed string: '%@'", [string trim]);
Category• Defining and using a Category
// File NSString+PMAddition.m @implementation NSString (PMAddition) - (NSString *)trim { NSCharacterSet *s = [NSCharacterSet whitespaceAndNewlineCharacterSet]; return [self stringByTrimmingCharactersInSet:s]; } @end
// File NSString+PMAddition.h @interface NSString (PMAddition) - (NSString *)trim; @end
iOS Bootcamp
Base Types
iOS Bootcamp
Weak and Strong Typing
• Weak-Typed object:
• Strong-Typed object:
• Compile-time and run-time type checking:
• Weak-Typed: call not exiting method => run-time error
• Strong-Typed: call not exiting method => compile-time warning => run-time error
id anObject;
BankAccount *anObject;
iOS Bootcamp
The nil object pointer
• Test for nil explicitly or implicitly:
• Can use in assignments and as arguments if expected
• Sending a message to nil?
if (nil == person) { //
person = nil; [button setTarget:nil];
person = nil; [person talk]; // If it’s nil, do nothing (no error!)
if (!person) { //
iOS Bootcamp
• Root Class
• Implements many basics
• Introspection
• Object equality
• String representation (description is like toString() in Java or ToString() in C#)
NSObject@interface BankAccount : NSObject
if ([anObject isKindOfClass:[Person class]]) {
if ([obj1 isEqual:obj2]) { // NOT obj1 == obj2
NSLog(@"%@", [anObject description]); NSLog(@"%@", anObject); // call description
iOS Bootcamp
• NSArray - ordered collection of objects
• NSDictionary - collection of key-value pairs
• NSSet - unordered collection of unique objects
Collections
NSDictionary *dic; dic = [[NSDictionary alloc] initWithObjectsAndKeys: @"ga", @"username", @"42", @"password", nil]; //nil to signify end of objects and keys.
iOS Bootcamp
• Collections can contain only objects
• Wrap primitive types in NSNumber or NSValue
• New literal syntax
Collections
NSArray *a = @[@"42", @42, @"42", @3.14]; !NSDictionary *d = @{ @1: @"black", @2: @"white"};
New in Xcode 4.4+
(WWDC 2012)
iOS Bootcamp
• Objective-C string literals start with @
• General-purpose Unicode string support
• NSString is immutable, NSMutableString is mutable
@”NSString”
const char *cString = "Pragma Mark"; // C string NSString *nsString = @"バンザイ"; // NSString @ !cString = [nsString UTF8String]; nsString = [NSString stringWithCString:cString encoding:NSUTF8StringEncoding];
iOS Bootcamp
Summary
iOS Bootcamp
• Objective-C is Fully C and Fully Object-Oriented
• Objective-C supports both strong and weak typing
• Objective-C is The Apple (only) Programming Language !
Objective-C
iOS Bootcamp
#pragma mark
iOS Bootcamp
One More Thing !