Koks skirtumas tarp atomų ir neatominių atributų?

Ką reiškia atomic ir nonatomic turto deklaravimas?

 @property(nonatomic, retain) UITextField *userName; @property(atomic, retain) UITextField *userName; @property(retain) UITextField *userName; 

Kokie yra šių trijų operacijų skirtumai?

1765 m
26 февр. Vasario 26 d 2009-02-26 05:31 '09, 5:31 val. 2009-02-26 05:31
@ 30 atsakymų

Paskutiniai du yra identiški; "Atominė" yra numatytasis elgesys ( ), tačiau tai nėra raktinis žodis, tačiau naujausių versijų llvm / nonatomic raktinis žodis buvo pridėtas tik kaip nonatomic .

Darant prielaidą, kad esate sintezės metodo įgyvendinimas, atominis ar neateminis modifikuoja sugeneruotą kodą. Jei rašote savo seterį / imtuvą, atominė / neatominė / taupymo / priskyrimo / kopijavimo funkcija yra tik rekomendacija. (Pastaba: dabar sintezė yra numatytasis elgesys pastarosiose LLVM versijose. Taip pat nereikia deklaruoti egzemplioriaus kintamųjų, jie taip pat bus automatiškai sintezuojami ir _ pridėta prie jų pavadinimo, kad būtų išvengta atsitiktinės tiesioginės prieigos).

Naudojant „atominį“, sintezuotas seteris / imtuvas užtikrina, kad sveikasis skaičius visada būtų grąžinamas iš imtuvo arba jį nustato montuotojas, neatsižvelgiant į seterio veiklą bet kuriame kitame sraute. Tai reiškia, kad jei A gija yra imtuvo viduryje, o B gija skambina setter, tikėtina, kad tikroji gyvybinga vertė bus automatiškai realizuotas objektas grąžinamas skambinančiajam A.

nonatomic tokiose garantijose nėra. Taigi, nonatomic žymiai greitesnis nei atominis.

Kas „atominė“ nedaro, garantuoja srautų saugumą. Jei sriegis A tuo pačiu metu, kaip ir B ir C srautai, vadina getter'ą, kuris vadina seterį su skirtingomis reikšmėmis, srautas A gali gauti bet kurią iš trijų grąžintų reikšmių - tai, kas vadinama, arba bet kokias vertes, perduodamas B ir C nustatytojams. vertė nuo B arba C, nenurodant.

Duomenų vientisumo užtikrinimas yra vienas iš pagrindinių kelių sričių programavimo tikslų - pasiekiamas kitomis priemonėmis.

Pridedama:

Vienos savybės atomicity taip pat negali garantuoti srauto saugumo, kai žaidime žaidžiami keli priklausomi požymiai.

Apsvarstykite:

  @property(atomic, copy) NSString *firstName; @property(atomic, copy) NSString *lastName; @property(readonly, atomic, copy) NSString *fullName; 

Šiuo atveju A gija gali pervardyti objektą skambindama setFirstName: ir paskui skambindami setLastName: Tuo tarpu B srautas gali skambinti „ fullName tarp „A“ ir dviejų skambučių ir gaus naują vardą kartu su senąja pavarde.

Norėdami išspręsti šią problemą, jums reikia sandorio modelio. Tai reiškia, kad kai kurie kiti sinchronizavimo tipai ir (arba) išimtys, kuriomis neįtraukiama prieiga prie „ fullName atnaujinant priklausomas savybes.

1700 m
26 февр. atsakymas pateiktas bbum 26 vasario mėn. 2009-02-26 09:40 '09 ne 9:40 2009-02-26 09:40

Tai paaiškinta „Apple“ dokumentuose , tačiau žemiau yra keletas pavyzdžių, kurie iš tikrųjų vyksta. Atkreipkite dėmesį, kad nėra „atominio“ raktinio žodžio, jei nenurodote „neatominės“, tada nuosavybė yra atominė, tačiau aiškiai nurodant „atominę“, atsiras klaida.

 //@property(nonatomic, retain) UITextField *userName; //Generates roughly - (UITextField *) userName { return userName; } - (void) setUserName:(UITextField *)userName_ { [userName_ retain]; [userName release]; userName = userName_; } 

Dabar atominė versija yra šiek tiek sudėtingesnė:

border=0
 //@property(retain) UITextField *userName; //Generates roughly - (UITextField *) userName { UITextField *retval = nil; @synchronized(self) { retval = [[userName retain] autorelease]; } return retval; } - (void) setUserName:(UITextField *)userName_ { @synchronized(self) { [userName_ retain]; [userName release]; userName = userName_; } } 

Iš esmės atominė versija turi užblokuoti, kad būtų užtikrintas srauto saugumas, ir taip pat iškelia nuorodų į objektą (ir automatizuojančią sąskaitą, kad ją subalansuotų) skaičių, kad skambintojui būtų užtikrintas garantuotas objektas, kitaip yra potencialus rasės būklė, jei kita gija nustato vertę , verčia skaičiuoti ref atstatyti į 0.

Tiesą sakant, yra daugybė skirtingų variantų, kaip šie dalykai veikia, priklausomai nuo to, ar savybės yra skaliarinės vertės ar objektai, ir kaip išsaugoti, kopijuoti, skaityti, ne atomus ir pan. bendrauti. Apskritai, savybių sintezatoriai tiesiog žino, kaip padaryti „teisingą dalyką“ visiems deriniams.

350
26 февр. Louis Gerbarg atsakymas, pateiktas vasario 26 d. 2009-02-26 09:24 '09 9:24 am. 2009-02-26 09:24

Atominė

  • - numatytasis elgesys
  • užtikrina, kad procesorius užbaigtų procesą, kol kitas procesas pasiekia kintamąjį
  • nėra greitas, nes jis visiškai užbaigia procesą

neateminis

  • NĖRA numatytasis elgesys.
  • greičiau (sintezuotam kodui, ty kintamiesiems, sukurtiems naudojant „@property“ ir „@synthesize“)
  • ne siūlas saugus
  • gali sukelti netikėtą elgesį, kai du skirtingi procesai tuo pačiu metu pasiekia tą patį kintamąjį
152
25 мая '12 в 13:56 2012-05-25 13:56 atsakymas pateikiamas „ raw3d“ gegužės 25 d., 12 val

Geriausias būdas suprasti skirtumą yra naudoti šį pavyzdį.

Tarkime, kad yra atominės eilutės ypatybė, vadinama "vardas", ir, jei skambinate [self setName:@"A"] iš A srauto, skambinkite [self setName:@"B"] iš B srauto ir skambinkite [self name] iš C srautas, tada visos operacijos su skirtingais siūlais bus atliekamos nuosekliai, o tai reiškia, kad jei vienas sriegis atlieka seterį ar imtuvą, tada kiti siūlai laukia.

Dėl to „vardas“ yra saugus skaitymui / rašymui, bet jei kitas temas, D, tuo pačiu metu skambina [name release] , ši operacija gali nepavykti, nes nėra jokio setter / getter skambučio. Tai reiškia, kad objektas yra saugus ir saugus (ATOMIC), bet nėra saugus, nes kiti siūlai vienu metu gali siųsti bet kokio tipo pranešimus objektui. Kūrėjas privalo užtikrinti tokių objektų siūlų saugą.

Jei "vardo" nuosavybė buvo neateminė, visi pirmiau pateiktame pavyzdyje - A, B, C ir D esantys srautai bus vykdomi vienu metu su bet kokio nenuspėjamo rezultato gavimo. Atomo atveju vienas iš A, B arba C vykdomas pirmiausia, bet D gali būti vykdomas lygiagrečiai.

128
31 янв. Atsakymas pateikiamas Vijayendra sausio 31 d 2012-01-31 21:36 '12 21:36 2012-01-31 21:36

Sintaksę ir semantiką jau gerai apibrėžia kiti puikūs atsakymai į šį klausimą. Kadangi įgyvendinimas ir veiklos rezultatai nėra labai išsamūs, pridėsiu savo atsakymą.

Koks yra funkcinis skirtumas tarp šių 3?

Aš visada manau, kad atominės medžiagos yra gana įdomios. Abstrakcijos lygmeniu mes dirbame naudojant atomo savybes, kurios yra klasės, kaip transporto priemonės, siekiant užtikrinti 100% srauto apsaugą. Iš tiesų gerai įsitvirtinusioms daugelio sriegių programoms programuotojo įsikišimas beveik neabejotinai yra reikalavimas. Tuo tarpu spektaklio charakteristikos ir savybės dar nėra išsamiai ištirtos. Per daugelį metų, parašęs kelias daugiasluoksnes programas, aš visada paskelbiau savo savybes kaip nonatomic , nes atomas nebuvo tinkamas bet kokiam tikslui. Aptardami šio klausimo atominių ir neatominių savybių detales, atlikiau kai kuriuos profilius, susidūrus su kai kuriais įdomiais rezultatais.

Vykdymas

Gerai. Pirmas dalykas, kurį norėčiau paaiškinti, yra tai, kad užrakto įgyvendinimas yra apibrėžtas ir išskaidytas. Louis savo pavyzdyje naudoja @synchronized(self) - aš tai matau kaip bendrą painiavos šaltinį. Įgyvendinimas iš tikrųjų nenaudoja @synchronized(self) ; jis naudoja objekto lygio užraktą. Louis iliustracijos puikiai tinka aukšto lygio iliustracijoms, naudojant visus žinomus konstruktus, tačiau svarbu žinoti, kad ji nenaudoja @synchronized(self) .

Kitas skirtumas yra tas, kad atominės savybės išlaikys / išlaisvins jūsų objektų ciklą imtuve.

Našumas

Čia yra įdomi dalis. Produktyvumas, naudojant prieigą prie atominių savybių neginčijamuose (pavyzdžiui, vieno sriegio) atvejais, kai kuriais atvejais gali būti labai greitas. Mažiau idealiu atveju atominės prieigos naudojimas gali kainuoti daugiau nei 20 kartų, palyginti su nonatomic paslaugų duomenimis. Nors ginčijamas argumentas naudojant 7 srautus buvo 44 kartus mažesnis trijų baitų struktūrai (2,2 GHz Core i7 Quad Core, x86_64). Trijų baitų struktūra yra labai lėto turto pavyzdys.

Įdomi pastaba: trijų baitų struktūros naudotojų prieigai buvo 52 kartus greitesni nei sintezuoti atomų priėjėjai; arba 84% - sintezuotų ne atomų priedų greitis.

Objektai ginčijamose bylose taip pat gali viršyti 50 kartų.

Atsižvelgiant į optimizavimo ir įgyvendinimo pokyčių skaičių, gana sunku įvertinti realaus pasaulio įtaką šiuose kontekstuose. Dažnai galite išgirsti kažką panašaus į „Pasitikėkite, jei neturite profilio ir nerandate, kad tai yra problema“. Dėl abstrakcijos lygio iš tikrųjų gana sunku išmatuoti tikrąjį poveikį. Faktinių profilių išlaidų išnykimas gali būti labai daug laiko ir dėl abstrakcijų gana netikslios. Be to, ARC ir MRC gali padaryti didelį skirtumą.

Taigi objc_msgSend žingsnį atgal, o ne sutelkdami dėmesį į prieigos nuosavybės įgyvendinimą, įtrauksime įprastus įtariamuosius, pvz., objc_msgSend , ir apsvarstysime kai kuriuos realius aukšto lygio rezultatus daugeliui skambučių į NSString getter neginčytinais atvejais (reikšmės sekundėmis):

  • MRC | nonatomic | rankiniu būdu įdiegti getters: 2
  • MRC | nonatomic | sintezuotas getter: 7
  • MRC | atomo | sintezuotas getter: 47
  • ARC | nonatomic | sintezuotas getter: 38 (pastaba: ARC prideda skaičiavimo ciklą)
  • ARC | atomo | sintezuotas getter: 47

Kaip jūs tikriausiai atspėjote, kovos / ciklinio aktyvumo aktyvumas reikšmingai prisideda prie atomo ir ARC. Taip pat pastebėsite didelius ginčijamų bylų skirtumus.

Nors aš atkreipiu dėmesį į atlikimą, aš vis dar sakau, kad Semantika pirma! . Tuo tarpu produktyvumas daugeliui projektų yra mažas prioritetas. Tačiau, žinant, kokių rezultatų jūs naudojate ir kokias technologijas naudojate, žinoma, nepažeidžiamas. Jūsų poreikius, tikslus ir sugebėjimus turite naudoti tinkama technologija. Tikiuosi, kad tai padės sutaupyti keletą valandų palyginimų ir padės jums priimti labiau pagrįstus sprendimus kuriant programas.

109
18 авг. atsakymas, pateiktas 18 d. 2012-08-18 12:47 '12 12:47 2012-08-18 12:47

Atominė = srauto sauga

Nonatominė = srauto sauga

Sriegių sauga:

Pavyzdžių kintamieji yra saugūs, jei jie elgiasi teisingai, kai jie pasiekiami iš kelių sriegių, neatsižvelgiant į tvarkaraščių sudarymą ar šių sričių vykdymo keitimą vykdant laiką ir be papildomo sinchronizavimo ar kito koordinavimo iš skambučio kodo pusės.

Mūsų kontekste:

Jei srautas keičia egzemplioriaus vertę, pakeista vertė prieinama visoms temoms, o tik viena gija gali keisti vertę vienu metu.

Kur naudoti atomic :

jei egzemplioriaus kintamasis yra prieinamas daugialypėje aplinkoje.

atomic išvestis:

Ne taip greitai, kaip ir nonatomic , nes nonatomic nereikalauja jokių budėjimo veiksmų nuo pat jo įvykdymo momento.

Kur naudoti nonatomic :

Jei egzemplioriaus kintamasis nėra pakeistas keliomis temomis, galite jį naudoti. Jis pagerina našumą.

92
10 июля '13 в 16:07 2013-07-10 16:07 atsakymą pateikė Durai Amuthan.H liepos 10 d. 13 d. 16:07 2013-07-10 16:07

Čia rado gana gerą atominių ir ne branduolinių savybių paaiškinimą. Štai keletas svarbių tekstų iš to paties:

„atominis“ reiškia, kad jis negali būti sugadintas. Kalbant apie OS / programavimą, atomo funkcijų skambutis yra toks, kurio negalima nutraukti - visa funkcija turi būti vykdoma, o ne iš CPU iškraunama įprastu operacinės sistemos konteksto perjungimu prieš jį baigiant. Tik tuo atveju, jei nežinojote: kadangi procesorius gali daryti tik vieną kartą, OS sukasi prieigą prie procesoriaus į visus veikiančius procesus mažais laiko skiltelėmis, kad sukurtų daugiafunkcinio darbo iliuziją. CPU planuotojas gali (ir) nutraukti procesą bet kuriuo metu jo vykdymo metu - net ir funkcijų skambučio viduryje. Todėl tokiems veiksmams, kaip atnaujinti bendrus skaičiuojamus kintamuosius, kai du procesai vienu metu gali bandyti atnaujinti kintamąjį, jie turi būti atliekami „atomiškai“, t.y. Kiekvienas atnaujinimo veiksmas turi baigtis visiškai, prieš bet kurį kitą procesą, kurį gali pakeisti CPU.

Taigi, norėčiau pasiūlyti, kad šiuo atveju atominis reiškia, kad atributų skaitymo metodai negali būti nutraukiami - iš esmės tai reiškia, kad metodas, kurį galima perskaityti, kintamasis (kintamasis) negali pakeisti jo vertės pusiaukelėje, nes kitas pokalbis / skambutis / funkcijų apsikeitimai CPU.

Kadangi atomic kintamieji negali būti nutraukiami, bet kurioje vietoje esanti jų vertė yra garantija , nors jei šis srauto užblokavimas daro prieigą prie jų lėčiau. Kita vertus, ne non-atomic kintamieji nesuteikia tokios garantijos, bet siūlo greitesnės prieigos prabangą. Apibendrinant, eikite su non-atomic , kai žinote, kad jūsų kintamieji nebus vienu metu prieinami keliose temose ir pagreitins procesą.

67
24 февр. atsakymas duotas tipycalFlow 24 vasaris 2012-02-24 08:17 '12 at 8:17 am 2012-02-24 08:17

Perskaičius tiek daug straipsnių: „Stack overflows“ ir „demo“ programų kūrimą, kad patikrintumėte kintamųjų savybių atributus, nusprendžiau visus atributų duomenis kartu:

  • atomic // numatytasis
  • nonatomic
  • strong = retain // numatytasis
  • weak = unsafe_unretained
  • retain
  • assign // pagal nutylėjimą
  • unsafe_unretained
  • copy
  • readonly
  • readwrite // default

Straipsnyje, turto atributuose arba turto modifikatoriuose, esančiuose „iOS“, galite rasti visus aukščiau nurodytus požymius, ir tai tikrai padės jums.

  • atomic

    • atomic reiškia, kad tik vienas sriegis pasiekia kintamąjį (statinį tipą).
    • atomic yra saugus siūlas.
    • Tačiau jis lėtai veikia
    • atomic - numatytasis elgesys
    • Atominės jungtys, esančios aplinkoje be šiukšlių (t.y. naudojant išsaugojimą / išleidimą / automatinį skelbimą), naudos spyną, užtikrinančią, kad kitas srautas netrukdytų teisingai nustatyti / gauti vertę.
    • Tai nėra raktinis žodis.

    Pavyzdys:

      @property (retain) NSString *name; @synthesize name; 
  • nonatomic

    • nonatomic reiškia, kad keli siūlai pasiekia kintamąjį (dinaminį tipą).
    • nonatomic yra nesaugus.
    • Bet tai veikia greitai.
    • nonatomic neveikia pagal nutylėjimą. Turime pridėti nonatomic raktinį žodį į nuosavybės atributą.
    • Tai gali sukelti netikėtą elgesį, kai du skirtingi procesai (siūlai) tuo pačiu metu pasiekia tą patį kintamąjį.

    Pavyzdys:

      @property (nonatomic, retain) NSString *name; @synthesize name; 
63
21 марта '13 в 10:10 2013-03-21 10:10 atsakymas pateikiamas swiftBoy kovo 21 d. 13 val. 10:10 2013-03-21 10:10

Atomic:

Atomic užtikrina, kad prieiga prie nuosavybės bus atliekama atominiu būdu. Pavyzdžiui. jis visuomet grąžina visiškai inicijuotus objektus, bet kokio vieneto gavimo / nustatymo ypatybės turi būti užpildytos prieš kitą prieigą prie jo.

Jei įsivaizduojate šią funkciją, kuri tuo pačiu metu atsiranda dviejose temose, galite suprasti, kodėl rezultatai nebus geri.

 -(void) setName:(NSString*)string { if (name) { [name release]; // what happens if the second thread jumps in now !? // name may be deleted, but our 'name' variable is still set! name = nil; } ... } 

Argumentai "už": visuomet grįžus į visiškai inicijuotus objektus, tai yra geriausias pasirinkimas daugiakalbės atveju.

Suvart: sumažėjęs našumas, šiek tiek lėtesnis vykdymas

Nonatominė:

Skirtingai nuo „Atomic“, ji nepateikia visiškai inicijuoto objekto grąžinimo kiekvieną kartą.

Argumentai "už": labai greitas vykdymas.

Suvart: šansai švaistyti daugiasluoksnės atliekos.

52
26 февр. Atsakymą pateikė Andrew Grant 26 vasaris. 2009-02-26 05:41 '09, 5:41 val. 2009-02-26 05:41

Paprasčiausias atsakymas: tarp jūsų antrojo dviejų pavyzdžių nėra jokio skirtumo. Pagal nutylėjimą nuosavybės prieigai yra atominiai.

Atominės prieigos aplinkoje, kurioje nėra šiukšlių (t.y., naudojant išsaugojimą / išleidimą / automatinį skelbimą), bus naudojamas užraktas, užtikrinantis, kad kitas srautas netrukdytų teisingai nustatyti / gauti vertę.

Daugiau informacijos ir kitų aplinkybių, kai kuriate daugiasukę programas, žr. „Apple Objective-C 2.0“ dokumentacijos skyriuje „ Veiklos ir srautai “.

52
26 февр. Atsakymą pateikė Jay O'Conor , vasario 26 d. 2009-02-26 05:56 '09, 5:56 val. 2009-02-26 05:56

Atominė reiškia, kad tik vienas sriegis pasiekia kintamąjį (statinį tipą). Atominė yra gija saugi, tačiau ji yra lėta.

„Nonatomic“ reiškia, kad kelios temos nurodo kintamąjį (dinaminį tipą). Neateminis - nesaugus srautas, bet jis yra greitas.

31
22 нояб. Atsakymą pateikė IOS Rocks lapkričio 22 d. 2012-11-22 14:20 '12 12:20 val. 2012-11-22 14:20

Atominė reiškia, kad tik vienas sriegis pasiekia kintamąjį (statinį tipą).

  • Atominė yra gija saugi.
  • Tačiau jis lėtai veikia
  • Atominė yra numatytasis elgesys.
  • Atominės prieigos aplinkoje, kurioje nėra šiukšlių (ty naudojant išsaugojimo / išleidimo / abstrakcijos), bus naudojamas užraktas, užtikrinantis, kad kitas sriegis netrukdytų teisingai nustatyti / išgauti vertę.
  • tai nėra raktinis žodis.

Pavyzdys:

 @property (retain) NSString *name; @synthesize name; 

„Nonatomic“ reiškia, kad kelios temos nurodo kintamąjį (dinaminį tipą).

  • Nepateminis - nesaugus srautas.
  • Bet tai veikia greitai.
  • Nonatomic nėra numatytasis elgesys, turėtume pridėti ne atomų raktinį žodį į nuosavybės atributą.
  • Tai gali sukelti netikėtą elgesį, kai du skirtingi procesai (siūlai) vienu metu pasiekia tą patį kintamąjį.

Pavyzdys:

 @property (nonatomic, retain) NSString *name; @synthesize name; 

Aš paaiškinu:

Tarkime, kad yra atominės eilutės ypatybė, vadinama „vardas“, ir, jei skambinate [savarankiškaiName: @ “A]] iš A srauto,

Skambinkite [self setName: @ "B"] iš B juostos ir skambinkite [self name] iš C, tada visos operacijos kitoje temoje bus vykdomos nuosekliai, o tai reiškia, kad jei vienas pokalbis atlieka seterį ar getter, tada kiti siūlai laukia . Это делает свойство "имя" безопасным для чтения/записи, но если другой поток D вызывает [имя выпуска] одновременно, то эта операция может привести к сбою, потому что здесь нет вызова setter/getter. Это означает, что объект безопасен для чтения/записи (ATOMIC), но не является потокобезопасным, поскольку другие потоки могут одновременно отправлять сообщения любого типа в объект. Разработчик должен обеспечить безопасность потоков для таких объектов.

Если свойство "name" было неатомным, то все потоки в приведенном выше примере - A, B, C и D будут выполняться одновременно с получением любого непредсказуемого результата. В случае атома, сначала выполняется один из A, B или C, но D может выполняться параллельно. - Подробнее: