Sök…


Automatisk referensräkning

Med automatisk referensräkning (ARC), kompilatorn insatserna retain , release och autorelease uttalanden där de behövs, så att du inte behöver skriva dem själv. Den skriver också dealloc metoder för dig.

Exempelprogrammet från Manual Memory Management ser ut så här med ARC:

@interface MyObject : NSObject {
    NSString *_property;
}
@end

@implementation MyObject
@synthesize property = _property;

- (id)initWithProperty:(NSString *)property {
    if (self = [super init]) {
        _property = property;
    }
    return self;
}

- (NSString *)property {
    return property;
}

- (void)setProperty:(NSString *)property {
    _property = property;
}

@end
int main() {
    MyObject *obj = [[MyObject alloc] init];
    
    NSString *value = [[NSString alloc] initWithString:@"value"];
    [obj setProperty:value];

    [obj setProperty:@"value"];
}

Du kan fortfarande åsidosätta dealloc-metoden för att rensa upp resurser som inte hanteras av ARC. Till skillnad från när man använder manuell minneshantering ringer du inte [super dealloc] .

-(void)dealloc {
   //clean up
}

Starka och svaga referenser

Modern

En svag referens ser ut som en av dessa:

@property (weak) NSString *property;
NSString *__weak variable;

Om du har en svag referens till ett objekt, sedan under huven:

  • Du behåller det inte.
  • När den delas om kommer varje hänvisning till den automatiskt att ställas in på nil

Objektreferenser är alltid starka som standard. Men du kan uttryckligen ange att de är starka:

@property (strong) NSString *property;
NSString *__strong variable;

En stark referens betyder att medan den referensen finns, behåller du objektet.

Manuell minnehantering

Detta är ett exempel på ett program skrivet med manuell minneshantering. Du borde verkligen inte skriva din kod så här, såvida du av någon anledning inte kan använda ARC (som om du behöver stödja 32-bitars). Exemplet undviker @property notering för att illustrera hur du brukade skriva böcker och setare.

@interface MyObject : NSObject {
    NSString *_property;
}
@end

@implementation MyObject
@synthesize property = _property;

- (id)initWithProperty:(NSString *)property {
    if (self = [super init]) {
        // Grab a reference to property to make sure it doesn't go away.
        // The reference is released in dealloc.
        _property = [property retain];
    }
    return self;
}

- (NSString *)property {
    return [[property retain] autorelease];
}

- (void)setProperty:(NSString *)property {
    // Retain, then release. So setting it to the same value won't lose the reference.
    [property retain];
    [_property release];
    _property = property;
}

- (void)dealloc {
    [_property release];
    [super dealloc]; // Don't forget!
}

@end
int main() {
    // create object
    // obj is a reference that we need to release
    MyObject *obj = [[MyObject alloc] init];
    
    // We have to release value because we created it.
    NSString *value = [[NSString alloc] initWithString:@"value"];
    [obj setProperty:value];
    [value release];

    // However, string constants never need to be released.
    [obj setProperty:@"value"];
    [obj release];
}

Regler för minneshantering när man använder manuell referensräkning.

Dessa regler gäller endast om du använder manuell referensräkning!

  1. Du äger alla objekt du skapar

    Genom att anropa en metod vars namn börjar med alloc , new , copy eller mutableCopy . Till exempel:

    NSObject *object1 = [[NSObject alloc] init];
    NSObject *object2 = [NSObject new];
    NSObject *object3 = [object2 copy];
    

    Det betyder att du är ansvarig för att släppa dessa föremål när du är klar med dem.

  2. Du kan ta ägande av ett objekt med behåll

    För att ta ägande för ett objekt kallar du behållningsmetoden.

    Till exempel:

    NSObject *object = [NSObject new]; // object already has a retain count of 1
    [object retain]; // retain count is now 2
    

    Detta är bara meningsfullt i vissa sällsynta situationer.

    Till exempel när du implementerar en accessor eller en init-metod för att ta ägande:

    - (void)setStringValue:(NSString *)stringValue {
        [_privateStringValue release]; // Release the old value, you no longer need it
        [stringValue retain]; // You make sure that this object does not get deallocated outside of your scope.
        _privateStringValue = stringValue;
    }
    
  3. När du inte längre behöver det måste du avstå från ägande av ett objekt du äger

    NSObject* object = [NSObject new]; // The retain count is now 1
    [object performAction1]; // Now we are done with the object
    [object release]; // Release the object
    
  4. Du får inte avstå från ägande av ett objekt du inte äger

    Det betyder att när du inte tog ägande av ett objekt släpper du inte det.

  5. Autoreleasepool

    Autoreleasepoolen är ett kodblock som släpper alla objekt i blocket som fick ett autoreleasmeddelande.

    Exempel:

    @autoreleasepool {
        NSString* string = [NSString stringWithString:@"We don't own this object"];
    }
    

    Vi har skapat en sträng utan att ta ägande. NSString metoden stringWithString: måste se till att strängen är korrekt omplacerad efter att den inte längre behövs. Innan metoden återgår anropar den nyligen skapade strängen autoreleasmetoden så att den inte behöver ta äganderätt till strängen.

    Så implementeras stringWithString: :

    + (NSString *)stringWithString:(NSString *)string {
        NSString *createdString = [[NSString alloc] initWithString:string];
        [createdString autorelease];
        return createdString;
    }
    

    Det är nödvändigt att använda autoreleasepool-block eftersom du ibland har objekt som du inte äger (de fjärde reglerna gäller inte alltid).

    Automatisk referensräkning tar automatiskt hand om reglerna så att du inte behöver göra det.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow