SlideShare a Scribd company logo
1 of 26
Objective-C Memory Management by Ahmed Magdy
Introduction ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
OUTLINE ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Reference Counting ,[object Object],[object Object],[object Object]
Object ownership ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Auto-release Pools ,[object Object],[object Object],[object Object],[object Object]
Auto-release pool  example @implementation Person -(void)startPlayWithPets { [NSThread detachNewThreadSelector:@selector(play)  toTarget:self withObject:nil]; } -(void)play { // without pool every autoreleased object will leak memory NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; // safe accessor returns autoreleased object, added to  thread’s autorelease pool NSArray* petsToPlay = [self pets] ;  BOOL allPetsAreHappy = NO; while(! allPetsAreHappy) { ... // some code, that may create autoreleased objects } [pool release]; // or [pool drain]; memory is freed, petsToPlay released as well } @end
Conventions ,[object Object],[object Object],[object Object]
Properties in Objective-C ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Properties in Objective-C  example 1 @property (nonatomic, retain) NSString* name; @synthesize name; // is equivalent to a pair of methods -(NSString*)name { return [[name retain] autorelease]; } -(void)setName:(NSString*)aName { if (name != aName) { [name release]; name = [aName retain]; } }
Properties in Objective-C  example 2 @property (atomic, copy) NSString* name;  // equivalent to  -(NSString*)name { NSString* retVal=nil; @synchronized(self) retVal = [[name retain] autorelease]; return retVal; } -(void)setName:(NSString*)aName { @synchronized(self)  if (name != aName) { [name release]; name = [aName copy]; } }
Rules of Thumb ,[object Object],[object Object],[object Object],[object Object]
Use autorelease for temporaries - (void) foo { NSString* s = [NSString string]; Or NSString* s = [[[NSString alloc] init] autorelease]; }
Retain & release members @interface Bar { NSString* _name; } @end - (id) init { if (self = [super init]) { _name = [[NSString alloc] init]; } return self; } - (void) dealloc { [_name release]; [super dealloc]; }
Use properties to get correct setters @interface Bar { NSString* _name; } @property(retain) NSString* name; @end @implementation @synthesize name = _name; - (void) dealloc { [_name release]; // still important because of _name [super dealloc]; } @end
Break rule 2 to avoid retain loops @interface Bar { id _delegate; } @property(assign) id delegate; // Note: not retain @end @interface Foo { Bar* _bar; } @end In Foo: _bar = [[Bar alloc] init]; _bar.delegate = self;
Common mistakes ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Premature Deletion - (void)init { if (self = [super init]) { _foo = [NSString string]; } } - (void)foo { NSLog(@”Foo is %@”, _foo); }
Double-deletion - (void) f { Bar* bar = [NSString string]; _foo = bar; } ... [pool release]  or [pool drain]; - (void)dealloc { [_foo release]; // retain count -1 [super dealloc]; }
No retain/release balance ,[object Object],[object Object],[object Object],[object Object]
[self release] - (void) someMethod { _name = @”the name”; _message = [[[NSString alloc] initWithFormat: @”my name is: ”, _name] autorelease]; [self release]; NSLog(_message); // error, if self is deallocated } - (void) dealloc { [_name release]; [_message release]; [super dealloc]; }
Reassign of pointer without releasing old value - (void) leak { NSString *name = [NSString alloc]  initWithFormat:@”%@”, @”Ahmed”]; name = @”Ali”; // the value @”Ahmed” is still there so there is a memory leak }
Overriding retain & release methods ,[object Object],[object Object]
Optimizations ,[object Object],[object Object],[object Object],[object Object],[object Object]
Summary ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Thank you

More Related Content

What's hot

Beginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCABeginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCA
Whymca
 
Multithreading and Parallelism on iOS [MobOS 2013]
 Multithreading and Parallelism on iOS [MobOS 2013] Multithreading and Parallelism on iOS [MobOS 2013]
Multithreading and Parallelism on iOS [MobOS 2013]
Kuba Břečka
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
Ignacio Martín
 

What's hot (20)

Connect.Tech- Swift Memory Management
Connect.Tech- Swift Memory ManagementConnect.Tech- Swift Memory Management
Connect.Tech- Swift Memory Management
 
iOS5 NewStuff
iOS5 NewStuffiOS5 NewStuff
iOS5 NewStuff
 
Beginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCABeginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCA
 
Multithreading and Parallelism on iOS [MobOS 2013]
 Multithreading and Parallelism on iOS [MobOS 2013] Multithreading and Parallelism on iOS [MobOS 2013]
Multithreading and Parallelism on iOS [MobOS 2013]
 
Hooks and Events in Drupal 8
Hooks and Events in Drupal 8Hooks and Events in Drupal 8
Hooks and Events in Drupal 8
 
【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう
【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう
【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう
 
Data perisistence in iOS
Data perisistence in iOSData perisistence in iOS
Data perisistence in iOS
 
Build Widgets
Build WidgetsBuild Widgets
Build Widgets
 
Realm.io par Clement Sauvage
Realm.io par Clement SauvageRealm.io par Clement Sauvage
Realm.io par Clement Sauvage
 
Events: The Object Oriented Hook System.
Events: The Object Oriented Hook System.Events: The Object Oriented Hook System.
Events: The Object Oriented Hook System.
 
The state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinThe state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon Dublin
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best Practices
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
iPhone Memory Management
iPhone Memory ManagementiPhone Memory Management
iPhone Memory Management
 
Javascript Application Architecture with Backbone.JS
Javascript Application Architecture with Backbone.JSJavascript Application Architecture with Backbone.JS
Javascript Application Architecture with Backbone.JS
 
Omnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the ThingsOmnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the Things
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 

Similar to Objective C Memory Management

ARCでめちゃモテiOSプログラマー
ARCでめちゃモテiOSプログラマーARCでめちゃモテiOSプログラマー
ARCでめちゃモテiOSプログラマー
Satoshi Asano
 
Closer Look - iPhone programming
Closer Look - iPhone programmingCloser Look - iPhone programming
Closer Look - iPhone programming
Sujith Krishnan
 
Rails' Next Top Model
Rails' Next Top ModelRails' Next Top Model
Rails' Next Top Model
Adam Keys
 
FI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS BasicsFI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS Basics
Petr Dvorak
 

Similar to Objective C Memory Management (20)

iPhone Seminar Part 2
iPhone Seminar Part 2iPhone Seminar Part 2
iPhone Seminar Part 2
 
Ios development
Ios developmentIos development
Ios development
 
iOS Session-2
iOS Session-2iOS Session-2
iOS Session-2
 
ARCでめちゃモテiOSプログラマー
ARCでめちゃモテiOSプログラマーARCでめちゃモテiOSプログラマー
ARCでめちゃモテiOSプログラマー
 
Objective-C & iPhone for .NET Developers
Objective-C & iPhone for .NET DevelopersObjective-C & iPhone for .NET Developers
Objective-C & iPhone for .NET Developers
 
MFF UK - Introduction to iOS
MFF UK - Introduction to iOSMFF UK - Introduction to iOS
MFF UK - Introduction to iOS
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not Java
 
Closer Look - iPhone programming
Closer Look - iPhone programmingCloser Look - iPhone programming
Closer Look - iPhone programming
 
Useful and Practical Functionalities in Realm
Useful and Practical Functionalities in RealmUseful and Practical Functionalities in Realm
Useful and Practical Functionalities in Realm
 
Rails' Next Top Model
Rails' Next Top ModelRails' Next Top Model
Rails' Next Top Model
 
Leaks & Zombies
Leaks & ZombiesLeaks & Zombies
Leaks & Zombies
 
Objective c
Objective cObjective c
Objective c
 
FI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS BasicsFI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS Basics
 
Lecture 3-ARC
Lecture 3-ARCLecture 3-ARC
Lecture 3-ARC
 
00-intro-to-classes.pdf
00-intro-to-classes.pdf00-intro-to-classes.pdf
00-intro-to-classes.pdf
 
Python_Unit_2 OOPS.pptx
Python_Unit_2  OOPS.pptxPython_Unit_2  OOPS.pptx
Python_Unit_2 OOPS.pptx
 
Web scraping using scrapy - zekeLabs
Web scraping using scrapy - zekeLabsWeb scraping using scrapy - zekeLabs
Web scraping using scrapy - zekeLabs
 
Django Good Practices
Django Good PracticesDjango Good Practices
Django Good Practices
 
Automatic Reference Counting @ Pragma Night
Automatic Reference Counting @ Pragma NightAutomatic Reference Counting @ Pragma Night
Automatic Reference Counting @ Pragma Night
 
Automatic Reference Counting
Automatic Reference CountingAutomatic Reference Counting
Automatic Reference Counting
 

More from Ahmed Magdy Ezzeldin, MSc.

Answer Selection and Validation for Arabic Questions
Answer Selection and Validation for Arabic QuestionsAnswer Selection and Validation for Arabic Questions
Answer Selection and Validation for Arabic Questions
Ahmed Magdy Ezzeldin, MSc.
 

More from Ahmed Magdy Ezzeldin, MSc. (12)

Distributed RDBMS: Challenges, Solutions & Trade-offs
Distributed RDBMS: Challenges, Solutions & Trade-offsDistributed RDBMS: Challenges, Solutions & Trade-offs
Distributed RDBMS: Challenges, Solutions & Trade-offs
 
Win any Interview like a Boss
Win any Interview like a BossWin any Interview like a Boss
Win any Interview like a Boss
 
Answer Selection and Validation for Arabic Questions
Answer Selection and Validation for Arabic QuestionsAnswer Selection and Validation for Arabic Questions
Answer Selection and Validation for Arabic Questions
 
Arabic Question Answering: Challenges, Tasks, Approaches, Test-sets, Tools, A...
Arabic Question Answering: Challenges, Tasks, Approaches, Test-sets, Tools, A...Arabic Question Answering: Challenges, Tasks, Approaches, Test-sets, Tools, A...
Arabic Question Answering: Challenges, Tasks, Approaches, Test-sets, Tools, A...
 
A survey of fault prediction using machine learning algorithms
A survey of fault prediction using machine learning algorithmsA survey of fault prediction using machine learning algorithms
A survey of fault prediction using machine learning algorithms
 
GATE : General Architecture for Text Engineering
GATE : General Architecture for Text EngineeringGATE : General Architecture for Text Engineering
GATE : General Architecture for Text Engineering
 
Networks and Natural Language Processing
Networks and Natural Language ProcessingNetworks and Natural Language Processing
Networks and Natural Language Processing
 
Distributed Coordination-Based Systems
Distributed Coordination-Based SystemsDistributed Coordination-Based Systems
Distributed Coordination-Based Systems
 
Distributed Systems Naming
Distributed Systems NamingDistributed Systems Naming
Distributed Systems Naming
 
Cyclcone a safe dialect of C
Cyclcone a safe dialect of CCyclcone a safe dialect of C
Cyclcone a safe dialect of C
 
Bash Scripting Workshop
Bash Scripting WorkshopBash Scripting Workshop
Bash Scripting Workshop
 
Object Role Modeling
Object Role ModelingObject Role Modeling
Object Role Modeling
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Recently uploaded (20)

Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 

Objective C Memory Management

  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7. Auto-release pool example @implementation Person -(void)startPlayWithPets { [NSThread detachNewThreadSelector:@selector(play) toTarget:self withObject:nil]; } -(void)play { // without pool every autoreleased object will leak memory NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; // safe accessor returns autoreleased object, added to thread’s autorelease pool NSArray* petsToPlay = [self pets] ; BOOL allPetsAreHappy = NO; while(! allPetsAreHappy) { ... // some code, that may create autoreleased objects } [pool release]; // or [pool drain]; memory is freed, petsToPlay released as well } @end
  • 8.
  • 9.
  • 10. Properties in Objective-C example 1 @property (nonatomic, retain) NSString* name; @synthesize name; // is equivalent to a pair of methods -(NSString*)name { return [[name retain] autorelease]; } -(void)setName:(NSString*)aName { if (name != aName) { [name release]; name = [aName retain]; } }
  • 11. Properties in Objective-C example 2 @property (atomic, copy) NSString* name; // equivalent to -(NSString*)name { NSString* retVal=nil; @synchronized(self) retVal = [[name retain] autorelease]; return retVal; } -(void)setName:(NSString*)aName { @synchronized(self) if (name != aName) { [name release]; name = [aName copy]; } }
  • 12.
  • 13. Use autorelease for temporaries - (void) foo { NSString* s = [NSString string]; Or NSString* s = [[[NSString alloc] init] autorelease]; }
  • 14. Retain & release members @interface Bar { NSString* _name; } @end - (id) init { if (self = [super init]) { _name = [[NSString alloc] init]; } return self; } - (void) dealloc { [_name release]; [super dealloc]; }
  • 15. Use properties to get correct setters @interface Bar { NSString* _name; } @property(retain) NSString* name; @end @implementation @synthesize name = _name; - (void) dealloc { [_name release]; // still important because of _name [super dealloc]; } @end
  • 16. Break rule 2 to avoid retain loops @interface Bar { id _delegate; } @property(assign) id delegate; // Note: not retain @end @interface Foo { Bar* _bar; } @end In Foo: _bar = [[Bar alloc] init]; _bar.delegate = self;
  • 17.
  • 18. Premature Deletion - (void)init { if (self = [super init]) { _foo = [NSString string]; } } - (void)foo { NSLog(@”Foo is %@”, _foo); }
  • 19. Double-deletion - (void) f { Bar* bar = [NSString string]; _foo = bar; } ... [pool release] or [pool drain]; - (void)dealloc { [_foo release]; // retain count -1 [super dealloc]; }
  • 20.
  • 21. [self release] - (void) someMethod { _name = @”the name”; _message = [[[NSString alloc] initWithFormat: @”my name is: ”, _name] autorelease]; [self release]; NSLog(_message); // error, if self is deallocated } - (void) dealloc { [_name release]; [_message release]; [super dealloc]; }
  • 22. Reassign of pointer without releasing old value - (void) leak { NSString *name = [NSString alloc] initWithFormat:@”%@”, @”Ahmed”]; name = @”Ali”; // the value @”Ahmed” is still there so there is a memory leak }
  • 23.
  • 24.
  • 25.