Key Terminology
- OTA: Over The Air download
- xcodeproj: Xcode project file
- IPA: iOS Application Archive (compiled app package)
- Provisioning Profile: Certificate that allows apps to run on devices
Historical Context
Why “NS” Prefix?
Objective-C was created by NeXT (the company founded by Steve Jobs after leaving Apple). NeXT introduced their object-oriented operating system called NeXTSTEP in the late 80s. Many Objective-C classes still use the “NS” prefix as a reference to NeXTSTEP.
Why “@” Symbol for Strings?
Objective-C is a strict superset of C, meaning you can compile any C code in an Objective-C project. However, in Objective-C we use object-oriented NSStrings instead of C strings. The @ symbol tells the compiler that what follows is an Objective-C NSString, not a C string.
Data Types
Primitive Data Types (5 total)
- int - integer (32-bit signed)
- float - floating point number (32-bit)
- double - double precision floating point number (64-bit)
- char - single character (8-bit)
- BOOL - YES or NO (essentially a char with special meaning)
Important: Everything else is a Class data type.
Additional Primitive Types
- NSInteger - Platform-specific integer (32-bit on 32-bit systems, 64-bit on 64-bit)
- NSUInteger - Unsigned platform-specific integer
- CGFloat - Platform-specific floating point (float on 32-bit, double on 64-bit)
Variables
- Variables identify values and are always strongly typed
- Every variable must be declared with one specific data type
// Variable declaration and assignment
int myInt;
myInt = 5;
// Declaration and initialization in one line
int myInt = 5;
// Platform-specific types (recommended for iOS)
NSInteger betterInt = 42;
CGFloat screenWidth = 320.0;
Format Specifiers for NSLog
%d- int%ld- NSInteger (long)%f- float, double%c- char%@- any object (e.g., NSString)%p- pointer address
Note: For BOOL values, use %d to get the integer value (0 for NO, 1 for YES)
NSString (Object Type)
All objects use pointers. A pointer holds a reference to a memory address instead of the actual value.
NSString *myString = @"Hello";
NSLog(@"What the what? %@", myString);
// String formatting
NSString *formatted = [NSString stringWithFormat:@"Number: %d", 42];
// Literal syntax (modern)
NSString *literal = @"This is a string literal";
Operators
Arithmetic Operators
+Add-Subtract*Multiply/Divide%Remainder (modulus)=Assignment+=Add right to left, assign to left-=Subtract right from left, assign to left*=Multiply left by right, assign to left/=Divide left by right, assign to left%=Left modulus right, assign to left++Increment by 1--Decrement by 1
Relational Operators
Work the same as other C-based languages:
==Equal to!=Not equal to<Less than<=Less than or equal to>Greater than>=Greater than or equal to
Logical Operators
Work the same as other C-based languages:
&&AND||OR!NOT
Custom Classes
Class Structure
- NSObject is the top-level parent class of all Objective-C classes
- Objective-C classes consist of two files:
- Interface file (.h) - “header” file containing class declarations
- Implementation file (.m) - contains actual class content
Interface File (.h)
Contains declarations visible to other classes, wrapped in @interface and @end:
#import <Foundation/Foundation.h>
@interface Person : NSObject
// Properties
@property (strong, nonatomic) NSString *firstName;
@property (strong, nonatomic) NSString *lastName;
@property (assign, nonatomic) NSInteger age;
// Method declarations
-(void)name:(NSString *)theName age:(int)theAge;
-(NSString *)fullName;
+(Person *)personWithName:(NSString *)name; // Class method
@end
Implementation File (.m)
Contains actual class content, wrapped in @implementation and @end:
#import "Person.h"
@implementation Person
-(void)name:(NSString *)theName age:(int)theAge
{
self.firstName = theName;
self.age = theAge;
}
-(NSString *)fullName
{
return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}
+(Person *)personWithName:(NSString *)name
{
Person *person = [[Person alloc] init];
person.firstName = name;
return person;
}
@end
Key Point: Everything inherits from NSObject - this is the foundation of the Objective-C class hierarchy.
Object Creation and Usage
Message Passing Philosophy
In Objective-C, you don’t “call methods” or “invoke functions” - you “send messages” to objects. This is a fundamental concept that distinguishes Objective-C from other languages.
Creating Objects
Class Methods vs Instance Methods
// Sending message to CLASS (class method)
Person *person = [Person new];
// Sending message to INSTANCE (instance method)
[person sayHi];
The new Method vs alloc/init
// Basic instantiation using new (rarely seen in practice)
Person *person = [Person new];
// Preferred method - explicit two-step process
Person *person = [[Person alloc] init];
// Custom initialization
Person *person = [[Person alloc] initWithName:@"John"];
Why the two-step approach is preferred:
- alloc - Allocate memory for the object
- init - Initialize the object (can use different init methods)
Property Access
Message Syntax
Person *person = [[Person alloc] init];
// Setting property via message
[person setFirstName:@"Mo"];
// Getting property via message
NSLog(@"%@", [person firstName]);
Dot Syntax (Syntactic Sugar)
Person *person = [[Person alloc] init];
// Setting property with dot syntax
person.firstName = @"Mo";
// Getting property with dot syntax
NSLog(@"%@", person.firstName);
Note: Both approaches are equivalent - dot syntax is just cleaner to read and write.
Methods (Messages)
Basic Method Syntax
// Instance method with no parameters
-(void)doSomething
{
}
// Instance method with one parameter
-(void)doSomething:(NSString *)firstThing
{
}
// Method with return value
-(NSString *)getFullName
{
return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}
// Class method (static)
+(Person *)createDefaultPerson
{
return [[Person alloc] init];
}
Named Parameters (Method Labels)
Objective-C supports descriptive method names with multiple labeled parameters:
// Interface declaration
@interface Person : NSObject
-(void)setName:(NSString *)theName age:(int)theAge;
-(void)moveToLocation:(NSString *)location withDistance:(float)distance;
@end
// Implementation
@implementation Person
-(void)setName:(NSString *)theName age:(int)theAge
{
self.firstName = theName;
self.age = theAge;
}
@end
// Usage
Person *person = [[Person alloc] init];
[person setName:@"John" age:25];
Method Components
- + Class method (static)
- - Instance method
- (void) Return type
- Colon required if there’s at least one argument
- Data type must be stated for parameters
- Each argument gets a name
Access Control
Properties
// Public property (in .h file)
@property (strong, nonatomic) NSString *firstName;
// Private property (in .m file, above @implementation)
@interface Person()
@property (strong, nonatomic) NSString *privateData;
@property (assign, nonatomic) BOOL isInitialized;
@end
Property Attributes
- strong - Strong reference (default for objects)
- weak - Weak reference (prevents retain cycles)
- assign - Simple assignment (default for primitives)
- copy - Makes a copy of the object
- atomic - Thread-safe (default, but slower)
- nonatomic - Not thread-safe (faster, commonly used)
- readonly - Only getter is generated
- readwrite - Both getter and setter generated (default)
Memory Management
Strong vs Weak References: The Dog Analogy
Strong Reference: Think of it like a dog on a leash. The dog wants to run away, but the strong reference is like the leash - as long as the pointer is strong, the dog (object) can’t run away (be deallocated).
Weak Reference: With a weak reference, the dog can run away. The object can be deallocated even if weak references still exist.
// Strong reference (default) - object stays alive
@property (strong, nonatomic) NSString *firstName;
// Weak reference - object can be deallocated
@property (weak, nonatomic) id<SomeDelegate> delegate;
// Copy - makes a copy of the object
@property (copy, nonatomic) NSString *immutableString;
When to use:
- Strong: Use for most cases (default behavior)
- Weak: Use for delegates and to prevent retain cycles
- Copy: Use for NSString and other value objects
MVC (Model View Controller)
Core Architecture Pattern
- Model - Data and business logic
- View - User interface elements
- Controller - Mediator between Model and View
Key MVC Principles
- Controller interacts with both Model and View
- Model and View should never communicate directly
- Every view has a controller, but not every controller has a view
- Some special controllers, called “controller of controllers” handle navigation
Interface Builder Connections
Connecting Views to Controllers
Connection process in Xcode:
- Ctrl+click and drag UI elements to code editor
- Choose connection type (IBOutlet or IBAction)
IBOutlet vs IBAction
// IBOutlet - allows code to reference UI elements
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UITextField *nameTextField;
// IBAction - handles user interactions (same as void)
-(IBAction)buttonTapped:(id)sender {
self.nameLabel.text = self.nameTextField.text;
}
Key Differences:
- IBOutlet: For displaying/reading UI elements (labels, text fields, etc.)
- IBAction: For responding to user interactions (button taps, etc.)
Simulator Controls
Rotation and Settings
- Command+Left or Command+Right rotates the simulator
- Can disable rotation by unchecking “Use Autolayout” in File Inspector for .xib file
- Apple Design Decision: Views won’t rotate when phone is upside down
Useful Simulator Shortcuts
- Command+Shift+H - Home button
- Command+K - Toggle software keyboard
- Hardware > Shake Gesture - Simulate device shake
Collections
Overview
Objective-C collection types:
- NSArray/NSMutableArray - Ordered list of objects
- NSSet/NSMutableSet - Unordered collection of unique objects
- NSDictionary/NSMutableDictionary - Key-value pairs
Important: Collections can only contain references to objects (not primitives directly).
NSArray (Immutable)
Must be completely populated at instantiation:
// Traditional syntax
NSArray *items = [[NSArray alloc] initWithObjects:@"ruby", @"c", @"c#", nil];
// Modern literal syntax (preferred)
NSArray *modernItems = @[@"swift", @"objective-c", @"javascript"];
// Accessing elements
NSString *firstItem = items[0]; // Modern syntax
NSString *firstItemOld = [items objectAtIndex:0]; // Traditional syntax
NSMutableArray
Can be modified after creation:
// Create empty mutable array
NSMutableArray *mutableItems = [[NSMutableArray alloc] init];
// Add objects
[mutableItems addObject:@"swift"];
[mutableItems insertObject:@"python" atIndex:0];
// Remove objects
[mutableItems removeObjectAtIndex:0];
[mutableItems removeObject:@"swift"];
Storing Primitives in Collections
Since collections only hold objects, wrap primitives in NSNumber:
// Storing numbers (traditional)
NSArray *numbers = @[[NSNumber numberWithInt:5], [NSNumber numberWithFloat:3.14]];
// Modern literal syntax for numbers
NSArray *modernNumbers = @[@5, @3.14, @YES];
// Retrieving values
int intValue = [numbers[0] intValue];
float floatValue = [numbers[1] floatValue];
NSDictionary
Key-value storage:
// Traditional syntax
NSDictionary *person = [[NSDictionary alloc] initWithObjectsAndKeys:
@"John", @"firstName",
@"Doe", @"lastName",
@25, @"age", nil];
// Modern literal syntax (preferred)
NSDictionary *modernPerson = @{
@"firstName": @"John",
@"lastName": @"Doe",
@"age": @25
};
// Accessing values
NSString *firstName = modernPerson[@"firstName"];
UI Controls and Interface
Labels
- Used for displaying text to users
- The view is always controlled by the ViewController (the “file owner”)
- Connected via IBOutlet for programmatic updates
@property (weak, nonatomic) IBOutlet UILabel *statusLabel;
// Updating label text
self.statusLabel.text = @"Ready";
self.statusLabel.textColor = [UIColor redColor];
Buttons
- Primary user interaction element
- Touch Up Inside: Most common event - triggered when user touches and releases
-(IBAction)buttonPressed:(UIButton *)sender {
sender.backgroundColor = [UIColor blueColor];
self.statusLabel.text = @"Button was pressed!";
}
Text Fields
@property (weak, nonatomic) IBOutlet UITextField *nameField;
// Getting text input
NSString *userInput = self.nameField.text;
// Setting placeholder text
self.nameField.placeholder = @"Enter your name";
The 44-Point Touch Target Rule
44x44 points is the minimum recommended touch target size for interactive elements.
This ensures:
- Comfortable tapping for all users
- Accessibility compliance
- Good user experience across different finger sizes
// Creating a properly-sized button programmatically
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(100, 100, 44, 44);
[button setTitle:@"Tap" forState:UIControlStateNormal];
Protocols and Delegates
Understanding Protocols
Protocols define a contract that classes can adopt:
// Protocol definition
@protocol PersonDelegate <NSObject>
@required
-(void)personDidChangeName:(Person *)person;
@optional
-(void)personDidChangeAge:(Person *)person;
@end
// Class adopting protocol
@interface PersonViewController : UIViewController <PersonDelegate>
@end
Delegate Pattern
// In the delegating class
@property (weak, nonatomic) id<PersonDelegate> delegate;
// Calling delegate methods
if ([self.delegate respondsToSelector:@selector(personDidChangeName:)]) {
[self.delegate personDidChangeName:self];
}
Common Patterns and Best Practices
Initialization Patterns
// Custom initializer
-(instancetype)initWithName:(NSString *)name age:(NSInteger)age
{
self = [super init];
if (self) {
_firstName = [name copy];
_age = age;
}
return self;
}
// Convenience constructor
+(instancetype)personWithName:(NSString *)name
{
return [[self alloc] initWithName:name age:0];
}
Error Handling
NSError *error = nil;
BOOL success = [self doSomethingThatMightFail:&error];
if (!success) {
NSLog(@"Error: %@", error.localizedDescription);
}
Key Concepts to Remember
- Message Passing: In Objective-C, you don’t “call methods” - you “send messages”
- Square Bracket Syntax:
[object message]is the standard way to send messages - Property Keywords:
@propertywith appropriate attributes for memory management - Two-File System: Always maintain both .h and .m files for custom classes
- NSObject Inheritance: All custom classes should inherit from NSObject
- MVC Pattern: Keep Model, View, and Controller responsibilities separate
- 44-Point Touch Targets: Minimum size for interactive elements
- Collections Hold Objects: Use NSNumber to wrap primitives for arrays
- Strong vs Weak: Understand memory management implications
- Protocols: Use for defining contracts and enabling loose coupling