objective-c @ itis
DESCRIPTION
Slides della sessione su Objective-C, tenuta da Giuseppe Arici all’iOS Bootcamp di pragmamark presso l'ITIS Castelli di Brescia.TRANSCRIPT
Giuseppe Arici § iOS Bootcamp @ ITIS
Objective-CThe Apple Programming Language
iOS Bootcamp @ ITIS
History
iOS Bootcamp @ ITIS
1976
Steve Jobs & Steve Wozniak @
iOS Bootcamp @ ITIS
1979
Apple Team @ Xerox PARC
iOS Bootcamp @ ITIS
1985
Steve Jobs ⚔ John Sculley
iOS Bootcamp @ ITIS
1986
NeXT Computer (∡28°)
iOS Bootcamp @ ITIS
1980
Brad Cox & Tom Love @ ITT
iOS Bootcamp @ ITIS
1986
OOP An Evolutionary Approach
iOS Bootcamp @ ITIS
1988
NeXT ® Objective-C ⚐ StepStone
iOS Bootcamp @ ITIS
1991
WWW & Doom & Mathematica
☢ NeXTcube
This machine is a server. DO NOT POWER DOWN !!
iOS Bootcamp @ ITIS
1996
NeXT ⊆ Apple
iOS Bootcamp @ ITIS
2001
Mac OS X v10.0
iOS Bootcamp @ ITIS
2007
The iPhone
iOS Bootcamp @ ITIS
2008
The iPhone SDK
iOS Bootcamp @ ITIS
Language
iOS Bootcamp @ ITIS
The Commandments
iOS Bootcamp @ ITIS
A strict superset of C
• Objective-C is a strict superset of the C language
• Objective-C is not inspired by C language like Java or C#
• Objective-C has only added some concepts and their associated keywords
• Like with C++, a well-written C program should be compile-able as Objective-C
• Unlike with C++, there is no risk of incompatibility between C names and Objective-C keywords
iOS Bootcamp @ ITIS
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
SELIMPnil Nil
BOOLYESNOid typ
edef
selfsuper
hidde
n par
amete
rsinoutinoutbycopy
byrefonewaygettersetter
readwritereadonlyassignretain
copynonatomicstrongweak av
ailab
le in
parti
cular
cont
exts
iOS Bootcamp @ ITIS
Requirements
iOS Bootcamp @ ITIS
*, &, [ ]
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 @ ITIS
Inheritance
Objective-C
MethodClass
Polymorphism
Abstraction
Encapsulation
Message passing
Instance VariableDelegation
SuperclassMethod overriding
Subclass
Dynamic dispatch / binding
Interface / Protocol
iOS Bootcamp @ ITIS
Class
iOS Bootcamp @ ITIS
Class
@implementation
// Person.m
#import "Person.h"
@implementation Person
@end
#import
@interface
// Person.h
@interface Person : NSObject
@end
iOS Bootcamp @ ITIS
Class @interface
iOS Bootcamp @ ITIS
Class @interface
#import <Foundation/Foundation.h>
@interface BankAccount : NSObject{ NSInteger _balance;}
- (NSInteger) withdraw:(NSInteger)amount;- (void) deposit:(NSInteger)amount;
@end
iOS Bootcamp @ ITIS
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 @ ITIS
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 @ ITIS
Class @interface
#import <Foundation/Foundation.h>
@interface BankAccount : NSObject{ NSInteger _balance;}
- (NSInteger) withdraw:(NSInteger)amount;- (void) deposit:(NSInteger)amount;
@end
class name
iOS Bootcamp @ ITIS
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 @ ITIS
Class @interface
#import <Foundation/Foundation.h>
@interface BankAccount : NSObject{ NSInteger _balance;}
- (NSInteger) withdraw:(NSInteger)amount;- (void) deposit:(NSInteger)amount;
@end
instancevariables
iOS Bootcamp @ ITIS
Class @interface
#import <Foundation/Foundation.h>
@interface BankAccount : NSObject{ NSInteger _balance;}
- (NSInteger) withdraw:(NSInteger)amount;- (void) deposit:(NSInteger)amount;
@endmethods
declarations
iOS Bootcamp @ ITIS
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 @ ITIS
Class @interface
#import <Foundation/Foundation.h>
@interface BankAccount : NSObject{ NSInteger _balance;}
- (NSInteger) withdraw:(NSInteger)amount;- (void) deposit:(NSInteger)amount;
@end
iOS Bootcamp @ ITIS
Class @implementation
iOS Bootcamp @ ITIS
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 @ ITIS
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
interfaceimport
iOS Bootcamp @ ITIS
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 @ ITIS
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 @ ITIS
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 @ ITIS
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 @ ITIS
Instance Variable Declaration
@interface MyClass : NSObject {
}
iOS Bootcamp @ ITIS
Instance Variable Declaration
@interface MyClass : NSObject { @private // Can only be accessed by instances of MyClass NSInteger _privateIvar1; NSString *_privateIvar2;
}
iOS Bootcamp @ ITIS
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 @ ITIS
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 @ ITIS
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 @ ITIS
@class directive
• @class directive provides minimal information about a class.
• @class indicates that the name you are referencing is a class!
• The use of the @class is known as a forward declaration
// Rectangle.m#import "Rectangle.h"
#import "Point.h"
@implementation Rectangle
- (Point *)center { // ...}@end
// Rectangle.h#import "Shape.h"
@class Point;
@interface Rectangle : Shape
- (Point *)center;
@end
iOS Bootcamp @ ITIS
Bad News
NO namespaces :(Use prefix instead !
NSObject, NSString, ...
UIButton, UILabel, ...
ABAddressBook, ABRecord, ...
// Pragma MarkPMDeveloper, PMEvent, ...
Draft Proposal for Namespaces in Objective-C: @namespace @usinghttp://www.optshiftk.com/2012/04/draft-proposal-for-namespaces-in-objective-c/
iOS Bootcamp @ ITIS
Method & Message
iOS Bootcamp @ ITIS
Method Declaration
- (BOOL) writeToFile:(NSString *)path atomically:(BOOL)flag;
iOS Bootcamp @ ITIS
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 @ ITIS
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 @ ITIS
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 @ ITIS
Method Declaration
- (BOOL) writeToFile:(NSString *)path atomically:(BOOL)flag;
argument type
Arguments come after or within the method name
argument name
iOS Bootcamp @ ITIS
[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 @ ITIS
Self & Super
• Methods have implicit reference to owning object called self (similar to Java and C# this, but self is a l-value)
• Additionally have access to superclass methods using super
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self reloadData];}
iOS Bootcamp @ ITIS
Object Life Cycle
iOS Bootcamp @ ITIS
Object Construction• NSObject defines class method called alloc
• Dynamically allocates memory for object on the heap
• Returns new instance of receiving class
• NSObject defines instance method called init
• Implemented by subclasses to initialize instance after memory has been allocated
• Subclasses commonly define several initializers (default indicated in documentation)
• alloc and init calls are always nested into single line
BankAccount *account = [BankAccount alloc];
BankAccount *account = [[BankAccount alloc] init];
[account init];
iOS Bootcamp @ ITIS
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 @ ITIS
Memory Management
iOS Bootcamp @ ITIS
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 @ ITIS
Memory Management
Reference Count
iOS Bootcamp @ ITIS
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 release, autorelease
• When count equals 0, runtime invokes dealloc
dealloc
iOS Bootcamp @ ITIS
Autorelease
• Instead of explicitly releasing something, you mark it for a later release
• An object called autorelease pool manages a set of objects to release when the pool is released
• Add an object to the release pool by calling autorelease
@autoreleasepool { // code goes here}
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];// code goes here[pool release];
iOS Bootcamp @ ITIS
Autorelease
• Autorelease is NOT a Garbage Collector ! It is deterministic ⌚
• Objects returned from methods are understood to be autoreleased if name is not in implicit retained set (alloc, new, init or copy)
• If you spawn your own thread, you’ll have to create your own NSAutoreleasePool
• Stack based: autorelease pools can be nested
Friday Q&A 2011-09-02: Let's Build NSAutoreleasePoolhttp://www.mikeash.com/pyblog/friday-qa-2011-09-02-lets-build-nsautoreleasepool.html
iOS Bootcamp @ ITIS
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-Chttp://pierre.chachatelier.fr/programmation/objective-c.php
iOS Bootcamp @ ITIS
Automatic Reference Counting
“Automatic Reference Counting (ARC) in Objective-C makes memory management the job of the compiler. By enabling ARC with the new Apple LLVM compiler, you will never need to type retain or release again, dramatically simplifying the development process, while reducing crashes and memory leaks. The compiler has a complete understanding of your objects, and releases each object the instant it is no longer used, so apps run as fast as ever, with predictable, smooth performance.”
(Apple, “iOS 5 for developers” – http://developer.apple.com/technologies/ios5)
iOS Bootcamp @ ITIS
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 @ ITIS
Property
iOS Bootcamp @ ITIS
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 @ ITIS
Property
• Objective-C 2.0 introduced new syntax for defining accessor code:
• Much less verbose, less error prone
• Highly configurable
• Automatically generates accessor code
• Complementary to existing conventions and technologies:
• Key-Value Coding (KVC)
• Key-Value Observing (KVO)
• Cocoa Bindings
• Core Data Simplifying Accessors
iOS Bootcamp @ ITIS
Property Declaration@property(attributes) type name;
Attribute Impacts
readonly / readwrite Mutability
setter / getter API
nonatomic Concurrency
assign / retain / copy weak / strong (* in ARC) Storage
iOS Bootcamp @ ITIS
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 @ ITIS
Property Declaration@property(attributes) type name;
Attribute Impacts
readonly / readwrite Mutability
setter / getter API
nonatomic Concurrency
assign / retain / copy weak / strong (* in ARC) Storage
@property(getter=isActive) BOOL active;
iOS Bootcamp @ ITIS
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 @ ITIS
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 @ ITIS
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 @ ITIS
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 @ ITIS
Property @implementation
#import "BankAccount.h"
@implementation BankAccount
//...
@synthesize accountNumber = _accountNumber;@synthesize balance = _balance;@synthesize fees = _fees;@synthesize active = _active;
//...
@end
iOS Bootcamp @ ITIS
Property @implementation
#import "BankAccount.h"
@implementation BankAccount
// No more @synthesize statements !
//...
@end
New in Xcode 4.4+
(WWDC 2012)
iOS Bootcamp @ ITIS
Protocol
iOS Bootcamp @ ITIS
Protocol
• List of method declarations
• Not associated with a particular class
• Conformance, not class, is important
• Useful in defining
• Methods that others are expected to implement
• Declaring an interface while hiding its particular class
• Capturing similarities among classes that aren't hierarchically related
Java / C# Interface done Objective-C style
iOS Bootcamp @ ITIS
Protocol
• Defining a Protocol
• Adopting a Protocol
@protocol NSCoding
- (void)encodeWithCoder:(NSCoder *)aCoder;- (id)initWithCoder:(NSCoder *)aDecoder;
@end
@interface Person : NSObject<NSCoding> { NSString *_name;}// method & property declarations@end
iOS Bootcamp @ ITIS
Base Types
iOS Bootcamp @ ITIS
Dynamic and Static Typing
• Dynamically-typed object:
• Just id
• Not id * (unless you really, really mean it: pointer to pointer)
• Statically-typed object:
• Objective-C provides compile-time type checking
id anObject;
BankAccount *anObject;
iOS Bootcamp @ ITIS
• Root Class
• Implements many basics
• Memory management
• 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
[anObject retain];
iOS Bootcamp @ ITIS
• Objective-C string literals start with @
• Consistently used in Cocoa instead of “const char *”
• General-purpose Unicode string support
• NSString is immutable, NSMutableString is mutable
@”NSString”
const char *cString = "Pragma Mark"; // C stringNSString *nsString = @"バンザイ"; // NSString @
cString = [nsString UTF8String];nsString = [NSString stringWithCString:cString
encoding:NSUTF8StringEncoding];
iOS Bootcamp @ ITIS
• NSArray - ordered collection of objects
• NSDictionary - collection of key-value pairs
• NSSet - unordered collection of unique objects
• Immutable and mutable versions
Collections
NSDictionary *dic;dic = [[NSDictionary alloc] initWithObjectsAndKeys: @"ga", @"username", @"42", @"password", nil]; //nil to signify end of objects and keys.
iOS Bootcamp @ ITIS
Summary
iOS Bootcamp @ ITIS
• 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 @ ITIS
Questions
?
iOS Bootcamp @ ITIS
One More Thing !
iOS Bootcamp @ ITIS
NSLog(@”Thank you!”);