Objective-C
#21
TIOBE#34
PYPL#10
GitHub#21
RedMonk#17
IEEESpectrum#27
JetBrains#20
Programming Language
Objective-C
Overview
Objective-C is a programming language that adds Smalltalk-style object-oriented features to the C language.
Details
Objective-C is a programming language developed by Brad Cox in the early 1980s, combining C language with Smalltalk's message-passing approach to create an object-oriented language. It was adopted by Apple as the primary development language for NeXTSTEP, and later for macOS and iOS, serving as the standard development language for Apple platforms for many years. While Swift has largely replaced it as Apple's preferred language, Objective-C remains important due to the vast existing codebase and libraries built with it, playing a crucial role in legacy system maintenance and compatibility with existing projects.
Code Examples
Hello World
// Basic output
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"Hello, World!");
// Output using variables
NSString *message = @"Hello, Objective-C!";
NSLog(@"%@", message);
// Output using format strings
NSString *name = @"John";
NSInteger age = 25;
NSLog(@"My name is %@ and I am %ld years old.", name, (long)age);
}
return 0;
}
Variables and Data Types
// Primitive types
NSInteger intValue = 42;
NSUInteger unsignedValue = 100;
CGFloat floatValue = 3.14f;
BOOL boolValue = YES;
// Object types
NSString *text = @"string";
NSNumber *numberObject = @(42);
NSArray *array = @[@"element1", @"element2", @"element3"];
NSDictionary *dictionary = @{
@"key1": @"value1",
@"key2": @"value2"
};
// Mutable objects
NSMutableString *mutableText = [NSMutableString stringWithString:@"initial"];
[mutableText appendString:@" appended"];
NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"A", @"B", nil];
[mutableArray addObject:@"C"];
NSLog(@"Integer: %ld", (long)intValue);
NSLog(@"String: %@", text);
NSLog(@"Array count: %lu", (unsigned long)[array count]);
Conditional Statements
// Basic if statement
NSInteger score = 85;
NSString *grade;
if (score >= 90) {
grade = @"A";
} else if (score >= 80) {
grade = @"B";
} else if (score >= 70) {
grade = @"C";
} else {
grade = @"D";
}
NSLog(@"Score: %ld, Grade: %@", (long)score, grade);
// Boolean conditions
NSInteger age = 20;
BOOL hasLicense = YES;
if (age >= 18 && hasLicense) {
NSLog(@"You can drive");
} else if (age >= 18) {
NSLog(@"Please get a license");
} else {
NSLog(@"Please get a license after turning 18");
}
// Switch statement
typedef NS_ENUM(NSInteger, DayOfWeek) {
Monday = 1,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
DayOfWeek today = Wednesday;
switch (today) {
case Monday:
case Tuesday:
case Wednesday:
case Thursday:
case Friday:
NSLog(@"It's a weekday");
break;
case Saturday:
case Sunday:
NSLog(@"It's weekend");
break;
}
Arrays and Dictionaries
// Array operations
NSArray *fruits = @[@"apple", @"banana", @"orange"];
NSLog(@"First fruit: %@", [fruits firstObject]);
NSLog(@"Fruit count: %lu", (unsigned long)[fruits count]);
// Processing array elements
for (NSString *fruit in fruits) {
NSLog(@"Fruit: %@", fruit);
}
// Index-based processing
for (NSUInteger i = 0; i < [fruits count]; i++) {
NSLog(@"Index %lu: %@", (unsigned long)i, fruits[i]);
}
// Mutable array
NSMutableArray *mutableFruits = [NSMutableArray arrayWithArray:fruits];
[mutableFruits addObject:@"grape"];
[mutableFruits insertObject:@"strawberry" atIndex:1];
// Dictionary operations
NSDictionary *person = @{
@"name": @"John Doe",
@"age": @30,
@"city": @"Tokyo"
};
NSLog(@"Name: %@", person[@"name"]);
NSLog(@"Age: %@", person[@"age"]);
// Processing dictionary keys and values
for (NSString *key in person) {
NSLog(@"%@: %@", key, person[key]);
}
// Mutable dictionary
NSMutableDictionary *mutablePerson = [NSMutableDictionary dictionaryWithDictionary:person];
mutablePerson[@"job"] = @"Engineer";
Loops and Iteration
// for-in loop
NSArray *numbers = @[@1, @2, @3, @4, @5];
for (NSNumber *number in numbers) {
NSInteger value = [number integerValue];
NSLog(@"Number: %ld, Double: %ld", (long)value, (long)(value * 2));
}
// Traditional for loop
for (NSInteger i = 1; i <= 5; i++) {
NSLog(@"Square of %ld is %ld", (long)i, (long)(i * i));
}
// while loop
NSInteger count = 0;
while (count < 5) {
NSLog(@"Count: %ld", (long)count);
count++;
}
// do-while loop
NSInteger counter = 0;
do {
NSLog(@"Execution count: %ld", (long)(counter + 1));
counter++;
} while (counter < 3);
Class Definition and Usage
// Header file (.h)
@interface Car : NSObject
@property (nonatomic, strong) NSString *make;
@property (nonatomic, strong) NSString *model;
@property (nonatomic, assign) NSInteger year;
@property (nonatomic, assign) NSInteger mileage;
- (instancetype)initWithMake:(NSString *)make model:(NSString *)model year:(NSInteger)year;
- (void)driveDistance:(NSInteger)distance;
- (NSString *)getInfo;
@end
// Implementation file (.m)
@implementation Car
- (instancetype)initWithMake:(NSString *)make model:(NSString *)model year:(NSInteger)year {
self = [super init];
if (self) {
_make = make;
_model = model;
_year = year;
_mileage = 0;
}
return self;
}
- (void)driveDistance:(NSInteger)distance {
self.mileage += distance;
NSLog(@"Drove %ldkm. Total mileage: %ldkm", (long)distance, (long)self.mileage);
}
- (NSString *)getInfo {
return [NSString stringWithFormat:@"%ld %@ %@", (long)self.year, self.make, self.model];
}
@end
// Usage example
Car *myCar = [[Car alloc] initWithMake:@"Toyota" model:@"Prius" year:2022];
NSLog(@"%@", [myCar getInfo]);
[myCar driveDistance:50];
[myCar driveDistance:30];
Protocols (Interfaces)
// Protocol definition
@protocol Drawable <NSObject>
@required
- (void)draw;
- (CGSize)getSize;
@optional
- (void)setColor:(UIColor *)color;
@end
// Class implementing protocol
@interface Circle : NSObject <Drawable>
@property (nonatomic, assign) CGFloat radius;
@end
@implementation Circle
- (void)draw {
NSLog(@"Drawing circle with radius %.2f", self.radius);
}
- (CGSize)getSize {
CGFloat diameter = self.radius * 2;
return CGSizeMake(diameter, diameter);
}
- (void)setColor:(UIColor *)color {
NSLog(@"Setting circle color");
}
@end
Categories (Extending Existing Classes)
// NSString category definition
@interface NSString (Utilities)
- (BOOL)isValidEmail;
- (NSString *)reverseString;
@end
@implementation NSString (Utilities)
- (BOOL)isValidEmail {
NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
return [emailTest evaluateWithObject:self];
}
- (NSString *)reverseString {
NSMutableString *reversedString = [NSMutableString string];
for (NSInteger i = [self length] - 1; i >= 0; i--) {
[reversedString appendString:[NSString stringWithFormat:@"%C", [self characterAtIndex:i]]];
}
return reversedString;
}
@end
// Usage example
NSString *email = @"[email protected]";
NSLog(@"Valid email: %@", [email isValidEmail] ? @"YES" : @"NO");
NSString *text = @"Hello";
NSLog(@"Reversed: %@", [text reverseString]);
Special Features
Memory Management (ARC and Manual)
// With ARC (Automatic Reference Counting)
@property (nonatomic, strong) NSString *strongProperty; // Strong reference
@property (nonatomic, weak) id<SomeDelegate> weakProperty; // Weak reference
@property (nonatomic, copy) NSString *copyProperty; // Copy property
// Blocks (closures)
typedef void (^CompletionBlock)(BOOL success, NSError *error);
- (void)performTaskWithCompletion:(CompletionBlock)completion {
// Asynchronous processing
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Some processing
BOOL success = YES;
NSError *error = nil;
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion(success, error);
}
});
});
}
KVO (Key-Value Observing)
// Register observer
[self addObserver:self
forKeyPath:@"someProperty"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
// Receive change notifications
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context {
if ([keyPath isEqualToString:@"someProperty"]) {
NSLog(@"Property changed: %@ -> %@",
change[NSKeyValueChangeOldKey],
change[NSKeyValueChangeNewKey]);
}
}
// Remove observer (important)
- (void)dealloc {
[self removeObserver:self forKeyPath:@"someProperty"];
}
Versions
Version | Status | Key Features | Release Year |
---|---|---|---|
Objective-C 2.0 | Current | Properties, Garbage Collection | 2007 |
Objective-C 1.0 | Legacy | Basic object-oriented features | 1988 |
Reference Pages
Official Documentation
- Apple Developer Documentation - Official documentation
- Objective-C Programming Language - Programming guide
- Cocoa Fundamentals Guide - Cocoa framework guide
Learning Resources
- Ray Wenderlich Objective-C Tutorials - Practical tutorials
- NSHipster - Detailed explanations of Objective-C and Cocoa
- Big Nerd Ranch Objective-C Programming - Books and learning resources