Properties and Synthesized Accessors
A property, declared with @property inside @interface, tells the compiler to generate a getter and setter method pair for a piece of instance state, plus a backing instance variable, without the developer having to hand-write that boilerplate. For example, @property (nonatomic, strong) NSString *name; automatically produces a name method (the getter) and a setName: method (the setter), backed by an ivar the compiler names _name by default.
Cricket analogy: Like a stadium's automated scoreboard system generating both the display and the update mechanism the moment a new statistic category is configured, rather than an operator wiring each one by hand, @property auto-generates a getter and setter the moment it's declared.
Property Attributes: Memory and Access
Property attributes in parentheses configure how the generated accessors behave: strong and weak control ownership under ARC (strong keeps the object alive, weak does not and auto-nils when the object is deallocated), copy makes an immutable snapshot at assignment time (essential for NSString and NSArray properties to prevent external mutation from affecting your copy), assign is used for primitives like NSInteger or BOOL, and readonly removes the generated setter entirely so the property can only be set internally. nonatomic (versus the default atomic) tells the compiler to skip the extra locking that guarantees thread-safe access, which is faster and is the overwhelming convention in UIKit-era Objective-C code since most properties are only touched from the main thread anyway.
Cricket analogy: Like a franchise deciding whether a player is under full contract (strong, keeping them on the roster) or just on a temporary loan that ends the moment the parent club recalls them (weak), Objective-C's strong and weak attributes control whether a property keeps its object alive.
@synthesize, Auto-Synthesis, and Custom Accessors
Before LLVM 4.0 (roughly Xcode 4.4), every property required an explicit @synthesize name = _name; line in @implementation to actually generate the getter, setter, and ivar; modern compilers do this automatically, so @synthesize is now rarely written except to rename the backing ivar or to synthesize a property declared in a protocol. A developer can also override the auto-generated getter or setter by simply writing a method with the matching name (for example, implementing - (void)setName:(NSString *)name { _name = [name copy]; NSLog(@"name changed"); } inside @implementation), which replaces the compiler-generated version while the property declaration in @interface stays unchanged.
Cricket analogy: Like modern professional grounds automatically preparing a standard pitch unless the head curator specifically requests a custom one for a day-night Test, auto-synthesis generates standard accessors unless a developer writes a custom override.
// Account.h
#import <Foundation/Foundation.h>
@interface Account : NSObject
@property (nonatomic, copy) NSString *ownerName;
@property (nonatomic, assign, readonly) double balance;
- (instancetype)initWithOwnerName:(NSString *)ownerName;
- (void)depositAmount:(double)amount;
@end
// Account.m
#import "Account.h"
@implementation Account
- (instancetype)initWithOwnerName:(NSString *)ownerName {
self = [super init];
if (self) {
_ownerName = [ownerName copy];
_balance = 0.0;
}
return self;
}
- (void)depositAmount:(double)amount {
if (amount > 0) {
_balance += amount;
}
}
// Custom setter override for a *different* property, kept nonatomic/copy semantics
- (void)setOwnerName:(NSString *)ownerName {
_ownerName = [ownerName copy];
NSLog(@"Owner renamed to %@", _ownerName);
}
@endThe @ synthesized backing ivar defaults to the property name with a leading underscore, so @property (nonatomic, strong) NSString *name; backs onto _name. Inside the class's own methods you can access _name directly or go through the accessor with self.name; outside the class, only self.name (or the bracket equivalent [obj name]) is available.
Declaring an NSString or NSArray property as strong instead of copy is a common bug source: if the caller passes in a mutable NSMutableString or NSMutableArray, a strong reference lets the caller mutate your object's internal state out from under you later, whereas copy captures an immutable snapshot at assignment time.
- @property auto-generates a getter, a setter, and a backing ivar for a piece of instance state.
- strong and weak control object ownership under ARC; weak references auto-nil on deallocation.
- copy takes an immutable snapshot at assignment, protecting against external mutation of mutable inputs.
- assign is used for primitive (non-object) properties like NSInteger, BOOL, and CGFloat.
- readonly removes the generated setter, restricting external code to reading the property only.
- nonatomic skips thread-safety locking for faster access and is the dominant convention in app code.
- Auto-synthesis generates accessors automatically; @synthesize is now mainly used to rename the backing ivar.
Practice what you learned
1. What does @property (nonatomic, strong) NSString *name; automatically generate?
2. Why is copy generally preferred over strong for an NSString property?
3. What happens to a weak property when the object it references is deallocated?
4. What does declaring a property readonly do?
5. What is the practical difference between atomic and nonatomic properties?
Was this page helpful?
You May Also Like
Classes and Objects in Objective-C
How Objective-C classes are declared with @interface/@implementation, and how objects are created via alloc and init.
ARC and Memory Management
How Automatic Reference Counting manages object lifetimes in Objective-C, and how it relates to the manual retain/release model it replaced.
Strong, Weak, and Retain Cycles
A deep look at how strong and weak references interact under ARC, and practical patterns for detecting and breaking retain cycles.
Objective-C Data Types
Objective-C's primitive types, Foundation typedefs like BOOL and NSInteger, and object types accessed through pointers.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics