目录


1 Memory Management

Item 29:Understand Reference Counting

  1. Reference-counting memory management is based on a counter that is incremented and decremented. An object is created with a count of at least 1. An object with a positive retain count is alive. When the retain count drops to 0, the object is destroyed.

  2. As it goes through its life cycle, an object is retained and released by other objects holding references to it. Retaining and releasing increments and decrements the retain count respectively.

Item 30:User ARC to Make Reference Counting Easier

  1. Method-Naming Rules Applied by ARC. alloc,new,copy,mutableCopy methods return an object owned by the caller method.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    + (EOCPerson*)newPerson {
        EOCPerson *person = [[EOCPerson alloc] init]; return person;
        /**
        * The method name begins with 'new', and since 'person' * already has an unbalanced +1 retain count from the
        * 'alloc', no retains, releases, or autoreleases are
        * required when returning.
        */
    }
    + (EOCPerson*)somePerson {
        EOCPerson *person = [[EOCPerson alloc] init]; return person;
        /**
        * The method name does not begin with one of the "owning"
        * prefixes, therefore ARC will add an autorelease when
        * returning 'person'.
        * The equivalent manual reference counting statement is:
        *
        */
    }
    
    - (void)doSomething {
        EOCPerson *personOne = [EOCPerson newPerson]; 
        // ...
    
        EOCPerson *personTwo = [EOCPerson somePerson]; 
        // ...
    
        /*
        * At this point, 'personOne' and 'personTwo' go out of scope, therefore ARC needs to clean them up as required. 
        * - 'personOne' was returned as owned by this block of code, so it needs to be released.
        * - 'personTwo' was returned not owned by this block of code, so it does not need to be released. 
        * The equivalent manual reference counting cleanup code is:
        * [personOne release];
        */
    }
    
  2. Memory-Management Semantics of Variables. _strong,_unsafe_unretained,__weak,_autoreleasing.
  3. ARC Handling of Instance Variables. ARC also handles the memory management of instance variables. Doing so requires ARC to automatically generate the required cleanup code during deallocation.
    1
    2
    3
    4
    5
    -(void) dealloc{
        [_foo release];
        [_bar release];
        [super dealloc];
    }
    
  4. Overriding the Memory-Management Methods

Item 31:Release References and Clean Up Observation State Only in dealloc

  1. The dealloc method should be used only to release references to other objects and to unregister anything that needs to be, such as Key-Value Observing(KVO) or NSNotificationCenter notifications.

  2. If an object holds onto system resources, such as file descriptors, there should be a method for releasing these resources. It should be the contract with the consumer of such a class to call this close method when finished using the resources.

  3. Method calls should be avoided in dealloc methods in case those methods try to perform asynchronous work or end up assuming that the object is in a normal state, which it won’t be.

Item 32:Beware of Memory Management with Exception-Safe Code

  1. When exceptions are caught, care should be taken to ensure that any required cleanup is done for objects created within the try block.

  2. By default, ARC does not emit code that handles cleanup when exceptions are thrown. This can be enabled with a compiler flag but produces code that is larger and comes with a runtime cost.

Item 33:Use Weak References to Avoid Retain Cycles

  1. Retain cycles can be avoided by making certain references weak.

  2. Weak references may or may not be autonilling. Autonilling is a new feature introduced with ARC and is implemented in the runtime. Autonilling weak references are always safe to read, as they will never contain a reference to a deallocated object.

Item 34:Use Autorelease Pool Blocks to Reduce High-Memory Waterline

  1. Autoreleas pools are arranged in a stack, with an object being added to the topmost pool when it is sent the autorelease message.
  2. Correct application of autorelease pools can help reduce the high-memory waterline of an application.
    1
    2
    3
    4
    5
    6
    7
    8
    NSArray *databaseRecords = /* ... */; 
    NSMutableArray *people = [NSMutableArray new]; 
    for (NSDictionary *record in databaseRecords) {
        @autoreleasepool { 
            EOCPerson *person =[[EOCPerson alloc] initWithRecord:record]; 
            [people addObject:person];
        } 
    }
    
  3. Modern autorelease pools using the new @autoreleasepool {} syntax are cheap.

Item 35:Use Zombies to Help Debug Memory-Management Problems

  1. When an object is deallocated, it can optionally be turned into a zombie instead of being deallocated. This feature is turned on by using the envrionment flag NSZombieEnabled.

  2. An object is turend into a zombie by manipulating its isa pointer to change the object’s class to a special zombie class. A zombie class responds to all selectors by aborting the application after printing a message to indicate what message was sent to what object.

Item 36:Avoid Using retainCount

  1. The retain count of an object might seem useful but usually is not, because the absolute retain count at any given time does not give a complete picture of an object’s lifetime.

  2. When ARC came along, the retainCount method was deprecated, and using it causes a compiler error to be emitted.

2 Reference


Share Post

Twitter Google+

Shunmian

The only programmers in a position to see all the differences in power between the various languages are those who understand the most powerful one.