Logo for tanaschita.com

Objective-C basics for Swift developers

Quick reference of key Objective-C concepts.

updated on 03 Jun 2024 · 6 min read

Objective-C, the primary language for iOS development before the release of Swift in 2014, remains an integral part of many legacy projects and Apple frameworks.

For Swift developers, understanding the basics of Objective-C can be valuable, especially when working on older codebases or integrating with libraries that haven’t been updated to Swift.

This guide will help Swift developers get acquainted with Objective-C, highlighting key concepts and differences between the two languages.

Let's jump in.

Sponsorship logo
Preparing for a technical iOS job interview - updated for iOS 17
Check out my book on preparing for a technical iOS job interview with over 200 questions & answers. Test your knowledge on iOS topics such as Swift, SwiftUI, Combine, HTTP Networking, Authentication, SwiftData & Core Data, Concurrency with async/await, Security, Automated Testing, Machine Learning and more.
LEARN MORE

Variables

Swift

When defining variables, Swift offers the let keyword for constants and the var keyword for variables. Swift offers type inference and optional data types.

let name = "Swifty" // declaring and assigning a constant
var age: Int? // declaring an optional Int variable
age = 7 // reassigning the variable
age = nil // nullifying the variable
var year = 2014 // the compiler automatically infers the `Int` type
let fruits = ["apple", "orange"] // desclaring and assigning an array of strings

Objective-C

Objective-C does not support type inference, we always have to explicitly specify the variable's type. It includes basic types like int, float, char and object types like NSString, NSNumber etc.

Unlike Swift, Objective-C does not have a separate optional type; all object types can inherently be nullified.

The same example in Objective-C looks as follows:

NSString const *name = @"Obji"; // declaring and assigning a constant
NSNumber *age; // declaring a variable
age = 7; // reassigning the variable
age = nil; // nullifying the variable
NSArray<NSString*> *fruits = @[@"apple", @"orange"]; // desclaring and assigning an array of strings

Let's go through some key points of the above example:

  • Explicit Type Declaration: Every variable must have its type explicitly declared.
  • Pointers: Object types are declared as pointers - which is indicated by *. This is conceptually similar to reference types in Swift but syntactically different.
  • Optionals: Swift’s optionals provide a clear way to handle nil values, whereas in Objective-C, any object can be set to nil.
  • Constants: const is used to declare constants.
  • Array syntax: The @ symbol is used before array literals.
  • String syntax: String literals are prefixed with @ to differentiate them from C-style strings.

Properties

In both Swift and Objective-C, properties are variables that are declared as part of a type. The primary difference lies in the syntax and additional attributes applied for access control and memory management.

Swift

In Swift, properties are commonly used in classes, structures, and enumerations. By default, properties are strong and have an internal access level unless otherwise specified.

class Child {
private let firstName: String // declaring a private constant property
private(set) var lastName: String // declaring a read-only property
var age: Int // declaring an internal property
weak public var parent: Parent? // declaring a weak public property
}

Objective-C

In Objective-C, properties are used only in classes and are declared using the @property keyword followed by comma-separated attributes specifying memory management and access control.

@property NSString *firstName; // declaring a strong property
@property (readonly) NSString *lastName; // declaring a read-only property
@property (weak) Parent *parent; // declaring a read-only property

The visibility of Objective-C properties is not achieved with attributes but with where we place them in our class declarations. We will look at that later in the classes section.

Methods

Swift

In Swift, methods can be defined on classes, structures, and enumerations. Swift methods support various features like default parameters, multiple return values and concise syntax.

// method declaration with no return type and no parameters
func emptyCard()
// method declaration with two parameters and a return value
func search(_ searchQuery: String, category: String) -> [Tea]
// default parameters
func walk(withSpeed speed: Int = 20)
// method implementation
func search(_ searchQuery: String, category: String) -> [Tea] {
return []
}
// calling a method
let results = teaShop.search("camomile", category: "herbs")

Objective-C

In Objective-C, only classes can define methods. Objective-C does not support default parameters, making method overloading a common pattern for similar functionality with different parameters.

// method declaration with no return type and no parameters
// `void` represents the absence of a type.
- (void)emptyCard;
// method declaration with two parameters and a return value
- (NSArray<Tea *> *)search:(NSString *)searchQuery category:(NSString *)category
// implementation of a method with two parameters and a return value
- (NSArray<Tea *> *)search:(NSString *)searchQuery category:(NSString *)category {
return [];
}
// calling a method
NSArray<NSString *> *results = [teaShop search:@"camomile" category:@"herbs"];

As shown above, methods in Objective-C have the - (returnType)methodName:(paramType)paramName syntax. To call a method, we use square brackets, with parameters specified within.

Classes & structs

Swift

In Swift, we distinguish between classes, which are reference types, and structs, which are value types.

import Foundation
class TeaShop {
// Public & private properties & methods
}
struct Tea {
// Public & private properties & methods
}
// Using a class
let shop = TeaShop()
// Using a struct
let tea = Tea()

Objective-C

In Objective-C, classes are defined using two separate files: the header file (.h) and the implementation file (.m). All classes are derived from the base class NSObject, which provides essential methods for memory allocation and initialization.

TeaShop.h

@import Foundation;
@interface TeaShop : NSObject
// Public properties & method definitions
@end

TeaShop.m

#import "TeaShop.h"
@interface TeaShop ()
// private properties & method definitions
@end
@implementation TeaShop {
// Private instance variables
}
// Methods implementation
@end

Creating a new object in Objective-C is a two-step process. First, we allocate memory for the object and then initialize it.

TeaShop *shop = [[TeaShop alloc] init];
// Or the shorter version, that will call `alloc` and `init` for us
TeaShop *shop = [[TeaShop new];

Structs in Objective-C are similar to C structs and are less commonly used compared to classes. Objective-C, being a superset of C, allows the use of C constructs.

// Declaration of a struct
struct Position
{
int x;
int y;
};
// Usage of a struct
struct Position position;
position.x = 5;
position.y = 10;

Enums

Swift

Like structs, Swift enums are first-class types which support features like associated types, computed properties, custom initializers and more.

enum TeeCategory {
case herbal
case green
case fruits
}
let category = TeeCategory.green

Objective-C

In Objective-C, enums are less flexible compared to Swift enums. They are essentially C-style enums, defined using the typedef keyword and NS_ENUM macro for better type safety and integration with Objective-C.

typedef NS_ENUM(NSInteger, TeeCategory) {
TeeCategoryHerbal,
TeeCategoryGreen,
TeeCategoryFruits
} TeeCategory;
// Using an enum
TeeCategory category = TeeCategoryFruits;

Extensions

Swift

In Swift, extensions are a powerful way to add new functionality to existing classes, structures, enums, or protocols without modifying their original implementation. Extensions can add computed properties, methods, initializers, and conform to protocols.

extension String {
var asURL: URL? {
URL(string: self)
}
}

Objective-C

In Objective-C, categories are used to add new functionality to existing classes. Categories, like classes, consist of a header file and an implementation file.

NSString+URL.h

@interface NSString (URL)
-(NSURL*)toURL;
@end

NSString+URL.m

#import "NSString+URL.h"
@implementation NSString (URL)
-(NSURL*)toURL {
return [[NSURL alloc] initWithString:self];
}
@end
Sponsorship logo
Preparing for a technical iOS job interview - updated for iOS 17
Check out my book on preparing for a technical iOS job interview with over 200 questions & answers. Test your knowledge on iOS topics such as Swift, SwiftUI, Combine, HTTP Networking, Authentication, SwiftData & Core Data, Concurrency with async/await, Security, Automated Testing, Machine Learning and more.
LEARN MORE

Newsletter

Image of a reading marmot
Subscribe

Like to support my work?

Say hi

Related tags

Articles with related topics

objective-c

swift

ios

How to import Objective-C types as optionals or non-optionals into Swift

Learn how to use nullability declarations and macros.

30 Jan 2023 · 3 min read

Latest articles and tips

© 2024 tanaschita.com

Privacy policy

Impressum