Objective-C iOS-kehitys vanhoille ja yrityssovelluksille · Oppitunti

Heikot ja vahvat viitteet

Erottakaa vahvat ja heikot viitteet toisistaan säilytyssilmukoiden estämiseksi ja olioiden elinkaarien tehokkaaksi hallitsemiseksi.

Oppitunti 3/411 vaihetta

Heikot ja vahvat viitteet on ilmainen Objective-C iOS-kehitys vanhoille ja yrityssovelluksille-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Objective-C iOS-kehitys vanhoille ja yrityssovelluksille-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Objective-C iOS-kehitys vanhoille ja yrityssovelluksille-kurssilla on yhteensä 4 oppituntia.

Olion elinkaaren ymmärtäminen

Objective-C:ssä olion elinkaaren hallinta on ratkaisevan tärkeää. Se tarkoittaa päättämistä, milloin olion tulee olla muistissa ja milloin sen voi turvallisesti poistaa.

Viitteillä ilmoitamme järjestelmälle, että 'välitämme' oliosta ja haluamme sen pysyvän elossa. Viitteitä on kaksi päätyyppiä: vahvat ja heikot.

Vahvat viitteet: oletusarvo

Vahva viite on ominaisuuksien ja muuttujien oletustyyppi Objective-C:ssä, kun käytössä on ARC (Automatic Reference Counting).

  • Se ilmaisee olion 'omistajuuden'.
  • Kun oliolla on vähintään yksi vahva viite, sitä ei voida vapauttaa.
  • Se kasvattaa olion retain-lukumäärää ja varmistaa, että olio säilyy muistissa.

Ajatelkaa sitä niin, että pidätte jostakin tiukasti kiinni: niin kauan kuin pidätte siitä kiinni, se ei katoa.

Esimerkki vahvasta viitteestä

Katsotaan vahvan viitteen toimintaa käytännössä. person1-muuttuja sisältää vahvan viitteen Person-olioon. Huomaatte, että dealloc-metodia kutsutaan, kun olioon ei enää viitata vahvasti.

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property (strong, nonatomic) NSString *name;
- (void)sayHello;
@end

@implementation Person
- (void)sayHello {
    NSLog(@"Hello, my name is %@", self.name);
}
- (void)dealloc {
    NSLog(@"Person %@ is being deallocated.", self.name);
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person1 = [[Person alloc] init];
        person1.name = @"Alice";
        NSLog(@"Person '%@' created.", person1.name);
        [person1 sayHello];
        // person1 goes out of scope at the end of @autoreleasepool
        // The Person object will be deallocated.
    }
    return 0;
}

Ongelma: retain-syklit

Vaikka vahvat viitteet ovat välttämättömiä, ne voivat aiheuttaa yleisen muistinhallintaongelman, jota kutsutaan retain-sykliksi (tai vahvojen viitteiden sykliksi).

Näin tapahtuu, kun vähintään kaksi oliota pitää vahvaa viitettä toisiinsa ja muodostaa suljetun silmukan. Koska jokaisella oliolla on syklin sisällä toisen olion vahva viite, niiden retain-lukumäärät eivät koskaan laske nollaan eikä niitä koskaan vapauteta.

Retain-syklin havainnollistaminen

Kuvitelkaa, että Parent-oliolla on vahva viite Child-olioon ja kyseisellä Child-oliolla on myös vahva viite Parent-olioon.

  • Parent sanoo: "Omistan Child-olion."
  • Child sanoo: "Omistan Parent-olion."

Kumpaakaan ei voida vapauttaa, koska toinen pitää yhä siitä kiinni, vaikka mikään muu sovelluksen osa ei enää tarvitsisi niitä. Tämä johtaa muistivuotoon.

Heikkojen viitteiden esittely

Heikot viitteet (jotka määritellään __weak-määreellä tai weak-ominaisuusmääreellä) on suunniteltu katkaisemaan retain-syklit.

  • Ne eivät kasvata olion retain-lukumäärää.
  • Ne eivät ilmaise omistajuutta.
  • Tärkeää on, että heikko viite muuttuu automaattisesti arvoksi nil, kun olio, johon se viittaa, vapautetaan.

Tämä 'nollautuminen' on erittäin turvallista ja estää roikkuvat osoittimet.

Heikon viitteen toiminta

Seuratkaa, miten heikko viite toimii. Kun olion viimeinen vahva viite vapautetaan, olio vapautetaan ja kaikki siihen osoittavat heikot viitteet muuttuvat automaattisesti arvoksi nil.

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property (strong, nonatomic) NSString *name;
- (void)dealloc;
@end

@implementation Person
- (void)dealloc {
    NSLog(@"Person %@ is being deallocated.", self.name);
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *strongPerson = [[Person alloc] init];
        strongPerson.name = @"Bob";
        
        __weak Person *weakPerson = strongPerson;
        
        NSLog(@"Before nil: strongPerson = %@, weakPerson = %@", strongPerson.name, weakPerson.name);
        
        strongPerson = nil; // Release the strong reference
        NSLog(@"Strong reference set to nil.");
        
        if (weakPerson) {
            NSLog(@"Weak Person still exists: %@", weakPerson.name);
        } else {
            NSLog(@"Weak Person is now nil.");
        }
    }
    return 0;
}

Retain-syklin katkaiseminen

Retain-syklin katkaisemiseksi yhden syklin viitteistä tulee olla heikko. Parent- ja Child-esimerkissämme on tavallista, että 'child'-oliolla on heikko viite 'parent'-olioon.

Tällöin parent omistaa child-olion, mutta child ei omista parent-oliota, joten molemmat voidaan vapauttaa asianmukaisesti.

#import <Foundation/Foundation.h>

@interface Parent : NSObject
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) id child; // Strong ref to child
- (void)dealloc;
@end

@interface Child : NSObject
@property (strong, nonatomic) NSString *name;
@property (weak, nonatomic) Parent *parent; // Weak ref to parent
- (void)dealloc;
@end

@implementation Parent
- (void)dealloc {
    NSLog(@"Parent %@ is being deallocated.", self.name);
}
@end

@implementation Child
- (void)dealloc {
    NSLog(@"Child %@ is being deallocated.", self.name);
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Parent *myParent = [[Parent alloc] init];
        myParent.name = @"Mom";
        
        Child *myChild = [[Child alloc] init];
        myChild.name = @"Alice";
        
        myParent.child = myChild; // Parent strongly references Child
        myChild.parent = myParent; // Child weakly references Parent
        
        NSLog(@"Parent and Child created. Releasing strong variables...");
        // Both objects will be deallocated as strong references from outside
        // the objects are released and the weak link doesn't prevent deallocation.
    }
    return 0;
}

`__weak` ja `__unsafe_unretained`

Saatatte kohdata myös __unsafe_unretained-määreen, joka on toinen omistajuutta ilmaisematon viitetyyppi. Suosikaa kuitenkin aina __weak-määrettä.

  • __weak: Muuttuu automaattisesti arvoksi nil, kun olio vapautetaan, ja estää kaatumiset.
  • __unsafe_unretained: Ei muutu arvoksi nil. Jos olio vapautetaan, viitteestä tulee roikkuva osoitin, joka aiheuttaa kaatumisen, jos sitä yritetään käyttää.

__weak on turvallisempi ja nykyaikaisessa ARC:tä käyttävässä Objective-C:ssä vakiintunut valinta.

Testatkaa tietonne

Mikä väite kuvaa parhaiten heikon viitteen ensisijaista tarkoitusta Objective-C:ssä ARC:n kanssa?

Kertaus: vahvat ja heikot viitteet

Olemme tarkastelleet vahvojen ja heikkojen viitteiden keskeistä eroa:

  • Vahvat viitteet: Oletusarvo, ilmaisevat omistajuutta, kasvattavat retain-lukumäärää ja pitävät oliot elossa.
  • Heikot viitteet: Eivät ilmaise omistajuutta eivätkä kasvata retain-lukumäärää, muuttuvat automaattisesti arvoksi nil ja ovat välttämättömiä retain-syklien katkaisemisessa.

Sen ymmärtäminen, milloin kumpaakin käytetään, on tärkeää muistivuotojen ehkäisemiseksi ja vankan Objective-C-koodin kirjoittamiseksi.

Aloita maksutta

Opi Objective-C tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
12
Oppitunnit
48

Usein kysytyt kysymykset

Onko oppitunti ”Heikot ja vahvat viitteet” ilmainen?

Kyllä – oppitunnin ”Heikot ja vahvat viitteet” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Objective-C iOS-kehitys vanhoille ja yrityssovelluksille-kurssin, päivitä CoddyKit PROhon. Objective-C iOS-kehitys vanhoille ja yrityssovelluksille-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Heikot ja vahvat viitteet”?

Erottakaa vahvat ja heikot viitteet toisistaan säilytyssilmukoiden estämiseksi ja olioiden elinkaarien tehokkaaksi hallitsemiseksi. Harjoittelet Objective-C iOS-kehitys vanhoille ja yrityssovelluksille-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Objective-C iOS-kehitys vanhoille ja yrityssovelluksille-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Objective-C iOS-kehitys vanhoille ja yrityssovelluksille-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Heikot ja vahvat viitteet”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Objective-C iOS-kehitys vanhoille ja yrityssovelluksille-oppitunnilla?

Kyllä. Jokainen Objective-C iOS-kehitys vanhoille ja yrityssovelluksille-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Manuaalisen retain-release-mallin (MRR) perusteet
  2. Automaattinen viitelaskenta (ARC)
  3. Heikot ja vahvat viitteet
  4. Retain-kiertojen katkaiseminen lohkoissa
← Takaisin: Objective-C iOS-kehitys vanhoille ja yrityssovelluksille