Atomik ve atomik olmayan özellikler arasındaki fark nedir?


Yanıtlar:


1761

Son ikisi aynı; "Atomic" varsayılan davranıştır ( aslında bir anahtar kelime olmadığını unutmayın; yalnızcanonatomic - yokluğu ile belirtildiğindeatomic , llvm / clang'ın son sürümlerinde bir anahtar kelime olarak eklendi).

Yöntem uygulamalarını sentezlediğinizi varsayarsak, atomik ve atomik olmayanlar üretilen kodu değiştirir. Kendi ayarlayıcı / alıcılarınızı yazıyorsanız, atomik / atomsuz / retain / ata / kopya sadece tavsiye niteliğindedir. (Not: @Synthesize artık LLVM'nin son sürümlerinde varsayılan davranıştır. Örnek değişkenleri bildirmeye de gerek yoktur; otomatik olarak da sentezlenecek ve _yanlışlıkla doğrudan erişimi önlemek için adlarının önüne eklenecektir).

"Atomik" ile, sentezlenen ayarlayıcı / alıcı, başka bir iş parçasındaki ayarlayıcı etkinliğine bakılmaksızın, alıcıdan her zaman bir tam değerin döndürülmesini veya ayarlayıcı tarafından ayarlanmasını sağlayacaktır. Yani, B iş parçacığı ayarlayıcıyı çağırırken A iş parçacığı alıcının ortasındaysa, gerçek bir geçerli değer - büyük olasılıkla otomatik olarak serbest bırakılmış bir nesne - A'daki arayana geri döner.

'De nonatomicböyle bir garanti verilmemektedir. Böylece, nonatomic"atom" dan oldukça hızlıdır.

Neyi "atomik" değil is yapmak iplik güvenliği konusunda hiçbir garanti. A iş parçacığı alıcıyı B ve C iş parçacığıyla aynı anda çağırıyorsa, ayarlayıcıyı farklı değerlerle çağırıyorsa, A iş parçacığı döndürülen üç değerden herhangi birini alabilir - herhangi bir ayarlayıcı çağrılmadan önceki veya ayarlayıcılara iletilen değerlerden biri Benzer şekilde, nesne, B ya da C değeriyle sonuçlanabilir, söylemenin bir yolu yoktur.

Veri bütünlüğünün sağlanması - çok iş parçacıklı programlamanın temel zorluklarından biri - diğer yollarla sağlanır.

Buna ekleniyor:

atomicity Tek bir özelliğin kullanılması, birden çok bağımlı özellik oyunda olduğunda iş parçacığı güvenliğini garanti edemez.

Düşünmek:

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

Bu durumda, A iş parçacığı çağırıp setFirstName:ardından çağırarak nesnenin adını değiştiriyor olabilir setLastName:. Bu arada, B fullNameiş parçacığı A iş parçacığının iki çağrısı arasında arama yapabilir ve eski soyadıyla birlikte yeni ad alır.

Bunu ele almak için işlemsel bir modele ihtiyacınız var . fullNameBağımlı özellikler güncellenirken erişimin hariç tutulmasına izin veren başka bir tür senkronizasyon ve / veya hariç tutma .


21
Herhangi bir iş parçacığı güvenli kodun kendi kilitleme vb. Yapacağı göz önüne alındığında, atomik özellik erişimcilerini ne zaman kullanmak istersiniz? İyi bir örnek düşünmekte güçlük çekiyorum.
Daniel Dickison

8
@bbum Mantıklı. İş parçacığı güvenliğinin model düzeyinde bir endişe olduğu yönündeki başka bir cevaba yaptığınız yorumu beğendim. Bir IBM iş parçacığı güvenliği tanımından: ibm.co/yTEbjY "Bir sınıf doğru şekilde uygulanırsa, bu onun belirtimine uygun olduğunu söylemenin başka bir yoludur, hiçbir işlem sırası (ortak alanları okur veya yazar ve genel yöntemlere çağrılar) bu sınıftaki nesnelerde nesneyi geçersiz duruma getirebilmeli, nesneyi geçersiz durumda gözlemleyebilmeli veya sınıfın değişmezlerini, önkoşullarını veya sonkoşullarını ihlal edebilmelidir. "
Ben Flynn

6
@StevenKramer 's benzeri bir örnek: @property NSArray* astronomicalEvents;Kullanıcı arayüzünde görüntülemek istediğim verileri listeleyen bir tane var. Uygulama işaretçi noktalarını boş bir diziye başlattığında, uygulama verileri web'den alır. Web isteği tamamlandığında (farklı bir iş parçacığında) uygulama yeni bir dizi oluşturur ve ardından özelliği atomik olarak yeni bir işaretçi değerine ayarlar. Güvenli bir iş parçacığı ve bir şey eksik sürece herhangi bir kilitleme kodu yazmak zorunda değildi. Bana oldukça faydalı geliyor.
bugloaf

10
@HotLicks Başka eğlenceli bir; belirli mimarilerde (hangisini hatırlayamıyorum), bağımsız değişken olarak iletilen 64 bit değerler yarının bir kaydında ve yarısında yığında geçirilebilir. atomicçapraz iplik yarı değer okumalarını önler. (
İzlemek

8
@congliu A İş parçacığı danssız bir nesne döndürür retain/autorelease. İş parçacığı B nesneyi serbest bırakır. A ipliği patlar . atomicA dişinin dönüş değeri için güçlü bir referansa (+1 alıkoyma sayısı) sahip olmasını sağlar.
bbum

360

Bu Apple'ın belgelerinde açıklanmıştır , ancak aşağıda gerçekte neler olduğuna dair bazı örnekler verilmiştir.

"Atomik" anahtar sözcüğü olmadığını unutmayın, "atom olmayan" belirtmezseniz, özellik atomiktir, ancak "atomik" ifadesinin açıkça belirtilmesi hataya neden olur.

"Atomik olmayan" belirtmezseniz, özellik atomiktir, ancak isterseniz son sürümlerde açıkça "atomik" belirtebilirsiniz.

//@property(nonatomic, retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    return userName;
}

- (void) setUserName:(UITextField *)userName_ {
    [userName_ retain];
    [userName release];
    userName = userName_;
}

Şimdi, atomik varyant biraz daha karmaşıktır:

//@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_;
    }
}

Temel olarak, atomik versiyonun iplik güvenliğini garanti etmek için bir kilit alması gerekir ve aynı zamanda nesne üzerindeki ref sayımını (ve dengelemek için otomatik serbest bırakma sayısını) çarpar, böylece nesnenin arayan için var olması garanti edilir, aksi takdirde başka bir evre değeri ayarlıyorsa, ref sayının 0'a düşmesine neden olan potansiyel bir yarış koşuludur.

Aslında, özelliklerin skaler değerler veya nesneler olup olmadığına ve tutma, kopyalama, salt okunur, anatomik olmayan, vb. Genel olarak, özellik sentezleyicileri tüm kombinasyonlar için "doğru olanı" nasıl yapacaklarını bilirler.


8
@Louis Gerbarg: Sana (şudur: userName == userName_) aynı nesneyi atamak denerseniz (nonatomic, korumak) setter sürümünüz düzgün çalışmaz inanıyoruz
Florin

5
Kodunuz biraz yanıltıcı; hangi atomik alıcıların / ayarlayıcıların senkronize edildiğine dair bir garanti yoktur . Kritik olarak, @property (assign) id delegate;hiçbir şeyle senkronize edilmez (iOS SDK GCC 4.2 ARM -Os), [self.delegate delegateMethod:self];ve arasında bir yarış olduğu anlamına gelir foo.delegate = nil; self.foo = nil; [super dealloc];. Bkz. Stackoverflow.com/questions/917884/…
tc.

@fyolnish Ne _val/ ne olduğundan emin değilim valama hayır, gerçekten değil. Bir atomik copy/ retainözellik için alıcı , ayarlayıcı başka bir iş parçacığında çağrıldığı için refcount sıfıra dönüşen bir nesneyi döndürmediğinden emin olmalıdır, bu da esas olarak ivar'ı okuması gerektiği anlamına gelir ve ayarlayıcının üzerine yazıp bıraktıktan sonra, tutmayı dengelemek için otomatik olarak serbest bırakın. Bu aslında hem alıcı hem de ayarlayıcının bir kilit kullanması gerektiği anlamına gelir (bellek düzeni sabitse, CAS2 talimatları ile yapılabilir olmalıdır; ne yazık ki -retainbir yöntem çağrısıdır).
tc.

@tc Oldukça uzun bir süre oldu ama yazmak istediğim muhtemelen şuydu : gist.github.com/fjolnir/5d96b3272c6255f6baae Ama evet eski değerin setFoo'dan önce bir okuyucu tarafından okunması mümkündür: okuyucu geri döner. Ama belki setter, -release yerine -autorelease kullandıysa, bunu düzeltirdi.
Fjölnir

@fyolnish Maalesef hayır: Bu, ayarlayıcının iş parçacığında otomatik olarak yayınlanırken, alıcının iş parçacığında otomatik olarak yayınlanması gerekir. Ayrıca, özyineleme kullandığınız için yığının tükenme şansı (ince) gibi görünüyor.
tc.

170

atomik

  • varsayılan davranış
  • başka bir işlem değişkene erişmeden önce mevcut işlemin CPU tarafından tamamlanmasını sağlayacaktır.
  • sürecin tamamen tamamlanmasını sağladığı için hızlı değil

Sigara Atom

  • varsayılan davranış DEĞİLDİR
  • daha hızlı (sentezlenmiş kod için, yani @property ve @synthesize kullanılarak oluşturulan değişkenler için)
  • güvenli değil
  • iki farklı işlem aynı değişkene aynı anda eriştiğinde beklenmeyen davranışlara neden olabilir

137

Farkı anlamanın en iyi yolu aşağıdaki örneği kullanmaktır.

"Name" adında bir atomik dize özelliği olduğunu varsayalım ve [self setName:@"A"]A [self setName:@"B"]iş parçacığından, B iş parçacığından ve [self name]C iş parçacığından çağrı yaparsanız , farklı iş parçacıklarındaki tüm işlemler seri olarak gerçekleştirilir, yani bir iş parçacığı bir ayarlayıcı yürütüyorsa veya getter, diğer iş parçacıkları bekleyecektir.

Bu özellik "name" okuma / yazma güvenli hale getirir, ancak başka bir iş parçacığı (D) [name release]aynı anda çağırırsa, burada ayarlayıcı / alıcı çağrısı olmadığından bu işlem çökebilir. Bu, bir nesnenin okuma / yazma için güvenli (ATOMIC) olduğu, ancak iş parçacığı için güvenli olmadığı anlamına gelir, çünkü başka bir iş parçacığı aynı anda nesneye her tür ileti gönderebilir. Geliştirici, bu tür nesneler için iş parçacığı güvenliğini sağlamalıdır.

"Name" özelliği anatomik değilse, yukarıdaki örnekteki tüm iş parçacıkları - A, B, C ve D eşzamanlı olarak yürütülür ve öngörülemeyen herhangi bir sonuç üretir. Atomik durumda, önce A, B veya C'den biri yürütülür, ancak D yine de paralel olarak çalışabilir.


116

Sözdizimi ve anlambilim, bu sorunun diğer mükemmel cevapları tarafından zaten iyi tanımlanmıştır. Çünkü yürütme ve performans de ayrıntılı değildir, benim cevap ekleyecektir.

Bu 3 arasındaki fonksiyonel fark nedir?

Atomik'i her zaman oldukça meraklı bir varsayılan olarak düşünürdüm. Çalıştığımız soyutlama seviyesinde, bir sınıfın atomik özelliklerini araç olarak% 100 iplik güvenliği elde etmek için kullanmak bir köşe durumudur. Gerçekten doğru çok iş parçacıklı programlar için, programcının müdahalesi neredeyse kesinlikle bir gerekliliktir. Bu arada, performans özellikleri ve yürütme henüz ayrıntılı olarak açıklanmamıştır. Yıllar boyunca çok sayıda çok iş parçacıklı program yazdıktan sonra, mülklerimi sürekli olarak ilan nonatomicediyordum çünkü atomik hiçbir amaç için mantıklı değildi. Bu sorunun atomik ve atomik olmayan özelliklerinin ayrıntıları tartışılırken, bazı profilleme bazı ilginç sonuçlarla karşılaştım.

infaz

Tamam. Temizlemek istediğim ilk şey, kilitleme uygulamasının uygulama tanımlı ve soyutlanmış olmasıdır. Louis @synchronized(self)örneğinde kullanıyor - bunu ortak bir karışıklık kaynağı olarak gördüm. Uygulama aslında kullanmaz @synchronized(self); nesne düzeyinde döndürme kilitleri kullanır . Louis'in illüstrasyonu, hepimizin aşina olduğu yapıları kullanan üst düzey bir illüstrasyon için iyidir, ancak kullanmadığını bilmek önemlidir @synchronized(self).

Başka bir fark, atomik özelliklerin alıcılarınızdaki nesnelerinizi koruyacağı / serbest bırakacağıdır.

Verim

İşte ilginç kısım: Tartışmasız (örneğin tek iş parçacıklı) durumlarda atomik özellik erişimini kullanan performans bazı durumlarda gerçekten çok hızlı olabilir. İdeal durumlardan daha az olan durumlarda, atomik erişimlerin kullanımı genel masrafın 20 katından daha pahalı olabilir nonatomic. İken Tartışmalı 7 konuları kullanarak vaka üç bayt yapı (2.2 GHz için 44 kat daha yavaş oldu Core i7 Dört Çekirdekli, x86_64). Üç baytlık yapı, çok yavaş bir özelliğe örnektir.

İlginç yan not: Üç baytlık yapının kullanıcı tanımlı erişimcileri, sentezlenen atomik erişimcilere göre 52 kat daha hızlıydı; veya% 84 sentezlenmiş anatomik olmayan erişimcilerin hızı.

İtiraz edilen davalardaki nesneler de 50 katını aşabilir.

Uygulamalardaki optimizasyonların ve varyasyonların sayısı nedeniyle, bu bağlamlardaki gerçek dünyadaki etkileri ölçmek oldukça zordur. Sık sık "Güven ve profil oluşturup bir sorun olduğunu düşünmedikçe" gibi bir şey duyabilirsiniz. Soyutlama seviyesi nedeniyle, gerçek etkiyi ölçmek aslında oldukça zordur. Profillerden gerçek maliyetleri düşürmek çok zaman alabilir ve soyutlamalardan dolayı oldukça yanlış olabilir. Ayrıca, ARC ve MRC arasında büyük bir fark olabilir.

Peki gelelim adım geri, değil mülkiyet erişimlerin uygulanmasına odaklanan biz gibi olağan şüpheliler ekleriz objc_msgSendve birçok aramalar için bazı gerçek dünya üst düzey sonuçlarını incelemek NSStringde getter rakipsiz durumlarda (saniye cinsinden değerler):

  • MRC | anatomik olmayan | elle uygulanan alıcılar: 2
  • MRC | anatomik olmayan | sentezlenmiş alıcı: 7
  • MRC | atomik | sentezlenmiş alıcı: 47
  • ARC | anatomik olmayan | sentezlenmiş alıcı: 38 (not: ARC burada ref sayımı ekliyor)
  • ARC | atomik | sentezlenmiş alıcı: 47

Muhtemelen tahmin ettiğiniz gibi, referans sayımı aktivitesi / döngüsü atomik ve ARC altında önemli bir katkıdır. Ayrıca, tartışmalı davalarda daha büyük farklılıklar görürsünüz.

Performansa çok dikkat etsem de, yine de Anlambilim Öncesi diyorum ! . Bu arada, performans birçok proje için düşük bir önceliktir. Ancak, kullandığınız teknolojilerin yürütme ayrıntılarını ve maliyetlerini bilmek kesinlikle zarar vermez. İhtiyaçlarınız, amaçlarınız ve yetenekleriniz için doğru teknolojiyi kullanmalısınız. Umarım bu size birkaç saatlik karşılaştırmaları kurtaracak ve programlarınızı tasarlarken daha bilinçli bir karar vermenize yardımcı olacaktır.


MRC | atomik | sentezlenmiş alıcı: 47 ARC | atomik | synthesized getter: 47 Onları aynı yapan nedir? ARC'nin daha fazla yükü olmamalı mı?
SDEZero

2
Yani atom özellikleri kötüyse y varsayılan değerlerdir. Isıtıcı kodunu artırmak için?
Kunal Balani

@ LearnCocos2D Ben sadece aynı makinede 10.8.5 üzerinde, 10.8, NSStringölümsüz olmayan bir tek dişli tartışmalı durumda için hedef test : -ARC atomic (BASELINE): 100% -ARC nonatomic, synthesised: 94% -ARC nonatomic, user defined: 86% -MRC nonatomic, user defined: 5% -MRC nonatomic, synthesised: 19% -MRC atomic: 102%- sonuçlar bugün biraz farklı. Hiçbir @synchronizedkarşılaştırma yapmıyordum . @synchronizedanlamsal olarak farklıdır ve önemsiz eşzamanlı programlarınız varsa iyi bir araç olarak düşünmüyorum. hıza ihtiyacınız varsa, kaçının @synchronized.
justin

bu testi çevrimiçi bir yerde yapıyor musun? Buraya benimkini eklemeye devam ediyorum: github.com/LearnCocos2D/LearnCocos2D/tree/master/…
LearnCocos2D 23:03

@ LearnCocos2D Onları insan tüketimi için hazırlamam, üzgünüm.
justin

95

Atomik = iplik güvenliği

Atomik değil = Diş güvenliği yok

İplik güvenliği:

Örnek değişkenleri, bu iş parçacıklarının çalışma zamanı ortamı tarafından yürütülmesinin planlanması veya serpiştirilmesinden bağımsız olarak ve çağıran kodun hiçbir ek senkronizasyonu veya başka bir koordinasyonu olmaksızın, birden çok iş parçacığından erişildiğinde doğru davranırlarsa iş parçacığı açısından güvenlidir.

Bağlamımızda:

Bir iş parçacığı örneğin değerini değiştirirse, değiştirilen değer tüm iş parçacıkları tarafından kullanılabilir ve aynı anda yalnızca bir iş parçacığı değeri değiştirebilir.

Nerede kullanılır atomic:

örnek değişkenine çok iş parçacıklı bir ortamda erişilecekse.

Aşağıdakilerin anlamı atomic:

Bu kadar hızlı değil, nonatomicçünkü nonatomicçalışma zamanından itibaren herhangi bir bekçi çalışması gerektirmez.

Nerede kullanılır nonatomic:

Örnek değişkeni birden çok iş parçacığı tarafından değiştirilmeyecekse bunu kullanabilirsiniz. Performansı artırır.


3
Burada söylediğin her şey doğru, ama son cümle esasen "yanlış", Dura, bugünkü programlama için. Bu şekilde "performansı artırmak" için uğraşmak gerçekten akıl almaz. (Yani, ışık yılı içine girmeden önce, "ARC kullanmıyorsunuz", "NSString kullanmıyorsunuz, çünkü yavaştır!" Ve benzeri.) Aşırı bir örnek vermek gerekirse, "takım, Bizi yavaşlattığı için koda herhangi bir yorum koymayın. " Güvenilmezlik uğruna (var olmayan) teorik performans kazanımlarını istediğiniz gerçekçi bir gelişme hattı yoktur.
Fattie

3
@JoeBlow, burada doğrulayabileceğiniz bir gerçektir developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…
Durai Amuthan.H

1
Durai FWIW, bu bağlantı doğrudan “Atom = iplik güvenliği” nin tez çelişmektedir. Apple'da açıkça, “Mülkiyet atomisitesi bir nesnenin iş parçacığı güvenliği ile eşanlamlı değil” diyor. Pratikte, atomik iplik güvenliğini sağlamak için nadiren yeterlidir.
Soymak

69

Burada atomik ve atomik olmayan özelliklerin oldukça iyi bir açıklamasını buldum . İşte aynı metinden bazı ilgili metinler:

'atomik' parçalanamayacağı anlamına gelir. İşletim sistemi / programlama terimlerinde bir atomik işlev çağrısı, kesilemeyen bir işlevdir - tüm işlev yürütülmelidir ve tamamlanana kadar işletim sisteminin olağan bağlam anahtarlamasıyla CPU'dan çıkarılmamalıdır. Bilmiyor olmanız durumunda: CPU bir seferde yalnızca bir şey yapabildiğinden, işletim sistemi, illüzyonu vermek için CPU'ya tüm çalışan işlemlere küçük zaman dilimleriyle dönerçoklu görev. CPU zamanlayıcı, işlemin herhangi bir noktasında - orta işlev çağrısında bile - bir işlemi kesebilir (ve keser). Bu nedenle, iki işlemin değişkeni aynı anda güncellemeye çalışabileceği paylaşılan sayaç değişkenlerini güncelleme gibi eylemler için, 'atomik olarak' yürütülmelidir, yani, herhangi bir işlemin başka herhangi bir işlemle değiştirilebilmesi için önce tamamlanması gerekir. İŞLEMCİ.

Bu durumda atomun öznitelik okuyucu yöntemlerinin kesilemeyeceği anlamına geldiğini tahmin ediyorum - aslında yöntem tarafından okunan değişken (ler), diğer bazı iş parçacığı / çağrı / işlev aldığından değerlerini yarıya kadar değiştiremez CPU üzerine takas edildi.

Çünkü atomicdeğişkenler kesilemez, herhangi bir noktada bunların içerdiği değer olması garanti (iplik kilidi) 'dir bozulmamış Konuyu kilit sağlanması yavaş onlara erişim sağlar, her ne kadar,. non-atomicdeğişkenler ise böyle bir garanti vermez, ancak daha hızlı erişim lüksü sunar. Özetlemek gerekirse non-atomic, değişkenlerinize aynı anda birden çok iş parçacığı tarafından erişilemeyeceğini bildiğinizde devam edin ve işleri hızlandırın.


1
Bağlantı koptu. ; (
Rob

Bağlantılar ile ilgili sorun bu :( Neyse ki,
cevabımda

67

Çok fazla makale okuduktan sonra Stack Overflow yayınları ve değişken özellik özelliklerini kontrol etmek için demo uygulamaları yaptıktan sonra, tüm özellik bilgilerini bir araya getirmeye karar verdim:

  1. atomic // Varsayılan
  2. nonatomic
  3. strong = retain // Varsayılan
  4. weak = unsafe_unretained
  5. retain
  6. assign // Varsayılan
  7. unsafe_unretained
  8. copy
  9. readonly
  10. readwrite // Varsayılan

İOS'taki Değişken özellik özellikleri veya değiştiricileri makalesinde , yukarıda belirtilen tüm özellikleri bulabilirsiniz ve bu kesinlikle size yardımcı olacaktır.

  1. atomic

    • atomic değişkene sadece bir iş parçacığı erişimi (statik tip) anlamına gelir.
    • atomic iş parçacığı için güvenlidir.
    • Ama performansta yavaş
    • atomic varsayılan davranış
    • Çöp toplanmayan bir ortamda bulunan atom erişimcileri (örneğin, tutma / bırakma / otomatik çalıştırma kullanılırken), başka bir iş parçacığının değerin doğru ayarlanmasını / alınmasını engellemediğinden emin olmak için bir kilit kullanır.
    • Aslında bir anahtar kelime değildir.

    Misal:

        @property (retain) NSString *name;
    
        @synthesize name;
  2. nonatomic

    • nonatomic değişkenin çoklu iş parçacığı erişimi anlamına gelir (dinamik tip).
    • nonatomic iş parçacığı güvensizdir.
    • Ama performansta hızlı
    • nonatomicvarsayılan davranış DEĞİLDİR. Eklemek zorundayıznonatomicAnahtar kelimeyi özellik özelliğine .
    • İki farklı işlem (iş parçacığı) aynı değişkene aynı anda eriştiğinde beklenmeyen davranışlara neden olabilir.

    Misal:

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

Nasıl atanabilir ve güçlü / tutulur?
BangOperator

güçlü ARC ile geliyor, koru ARC önce varsayılan oldu
abdullahselek

56

Atomik:

Atomik, mülke erişimin atomik bir şekilde gerçekleştirileceğini garanti eder. Örneğin, her zaman tamamen başlatılmış bir nesne döndürür; bir iş parçacığındaki herhangi bir özellik / get özelliği, diğerinin erişebilmesi için tamamlanmalıdır.

Aşağıdaki işlevin aynı anda iki iş parçacığında meydana geldiğini hayal ediyorsanız, sonuçların neden hoş olmadığını görebilirsiniz.

-(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;
  }

  ...
}

Artıları: Her seferinde tamamen başlatılmış nesnelerin geri dönüşü, çoklu iş parçacığı durumunda en iyi seçimdir.

Eksileri: Performans isabet, yürütmeyi biraz yavaşlatır

Atom Dışı:

Atomic'ten farklı olarak, her seferinde tamamen başlatılmış nesnenin geri dönüşünü sağlamaz.

Artıları: Son derece hızlı yürütme.

Eksileri: Çoklu iplik geçirme durumunda çöp değeri olasılığı.


5
Bu yorum pek mantıklı değil. Açıklayabilir misin? Apple sitesindeki örneklere bakarsanız, atomik anahtar kelime, özellikleri güncellenirken nesne üzerinde senkronize edilir.
Andrew Grant

52

Önce en kolay cevap: İkinci iki örneğiniz arasında hiçbir fark yoktur. Varsayılan olarak, özellik erişimcileri atomiktir.

Çöp toplanmayan bir ortamda bulunan atom erişimcileri (örneğin, tutma / bırakma / otomatik çalıştırma kullanılırken), başka bir iş parçacığının değerin doğru ayarlanmasını / alınmasını engellemediğinden emin olmak için bir kilit kullanır.

Daha fazla bilgi ve çok iş parçacıklı uygulamalar oluştururken dikkat edilecek diğer noktalar için Apple'ın Objective-C 2.0 belgelerinin " Performans ve İş Parçacığı " bölümüne bakın.


8
İki sebep. İlk olarak, sentezlenmiş kod için daha hızlı üretir (ancak threadsafe kodu oluşturmaz). İkincisi, atomik olmayan müşteri erişimcileri yazıyorsanız, gelecekteki herhangi bir kullanıcı için, kodları, arabirimini okurken, uygulama yapmadan atomik olmadığını açıklamanıza izin verir.
Louis Gerbarg


31

Atomik, değişkenin (statik tip) yalnızca bir iş parçacığına eriştiği anlamına gelir. Atomik iplik korumalıdır, ancak yavaştır.

Nonatomik, birden çok iş parçacığının değişkene (dinamik tip) eriştiği anlamına gelir. Nonatomik iplik güvensizdir, ancak hızlıdır.


14

Atomik iplik korumalıdır , yavaştır ve iyi garanti eder (garanti edilmez) aynı bölgeye kaç iş parçacığı girmeye çalıştığından bağımsız olarak yalnızca kilitli değerin sağlanmasını . Atomik kullanırken, bu fonksiyonun içine yazılan bir kod parçası, kritik bölümün bir parçası haline gelir ve bir seferde yalnızca bir iş parçacığının yürütülebileceği bir parça haline gelir.

Sadece iplik güvenliğini sağlar; bunu garanti etmez. Demek istediğim, arabanız için uzman bir sürücü kiralamanız, yine de arabanın bir kaza ile karşılaşmayacağını garanti etmiyor. Ancak, olasılık en düşük seviyede kalmaktadır.

Atomik - parçalanamaz, bu yüzden sonuç bekleniyor. Otomatik olmayan - başka bir iş parçacığı bellek bölgesine eriştiğinde onu değiştirebilir, böylece sonuç beklenmedik olur.

Kod Konuşma:

Atomik özellik ipliği alıcı ve ayarlayıcı güvenli hale getirir. örneğin u yazdıysanız:

self.myProperty = value;

iş parçacığı için güvenlidir.

[myArray addObject:@"Abc"] 

güvenli değil.


Son paragrafın nasıl geldiğini bilmiyorum, ama basit yanlış, "özel kopya" gibi bir şey yok.
zirve

13

Böyle bir "atomik" anahtar kelimesi yok

@property(atomic, retain) UITextField *userName;

Yukarıdaki gibi kullanabiliriz

@property(retain) UITextField *userName;

Yığın Taşması sorusuna bakın @property (atomik, tutma) NSString * myString kullanırsam sorunlar alıyorum .


10
"Böyle bir anahtar kelime var", Anahtar kelimenin varsayılan olarak gerekli olmadığını ve hatta varsayılan değer, anahtar kelimenin var olmadığı anlamına gelmez.
Matthijn

4
Bu yanlış. Anahtar kelime var. Bu cevap yanıltıcıdır ve ben de bunu alt etmeyi teşvik ederim.
sethfri

12

atomik (varsayılan)

Atomic varsayılan değerdir: hiçbir şey yazmazsanız mülkünüz atomiktir. Atomik bir özellik, ondan okumaya çalışırsanız, geçerli bir değer alacağınız garanti edilir. Bu değerin ne olabileceği konusunda herhangi bir garanti vermez, ancak sadece gereksiz hafızaya değil, iyi verileri geri alırsınız. Bu, tek bir değişkeni işaret eden birden çok iş parçacığına veya birden çok işleme sahipseniz, bir iş parçacığı okuyabilir ve başka bir iş parçacığı yazabilirse bunu yapmanıza izin verir. Aynı anda vururlarsa, okuyucu iş parçacığının iki değerden birini alması garanti edilir: değişiklikten önce veya değişiklikten sonra. Atomun size vermediği, bu değerlerden hangisini alabileceğiniz konusunda herhangi bir garanti. Atomic gerçekten yaygın olarak iş parçacığı açısından güvenli olmakla karıştırılır ve bu doğru değildir. İplik güvenliğinizi diğer yollarla garanti etmeniz gerekir.

nonatomic

Flip tarafında, atomik olmayan, tahmin edebileceğiniz gibi, sadece “o atomik şeyleri yapma” anlamına gelir. Kaybettiğiniz şey, her zaman bir şeyleri geri alabileceğinizin garantisidir. Bir yazının ortasında okumaya çalışırsanız, çöp verilerini geri alabilirsiniz. Ancak, diğer taraftan, biraz daha hızlı gidersiniz. Atomik özelliklerin bir değeri geri alacağınızı garanti etmek için biraz sihir yapması gerektiğinden, biraz daha yavaştırlar. Çok eriştiğiniz bir mülkse, bu hız cezasına maruz kalmamaya emin olmak için anatomik olmayana bırakmak isteyebilirsiniz.

Buradan daha fazlasını görün: https://realm.io/news/tmi-objective-c-property-attributes/


11

Varsayılan olan atomicbu araçlar size özelliğini her kullandığınızda size performans ödemek, ama o iş parçacığı güvenlidir. Objective-C'nin yaptığı bir kilit ayarlanır, böylece ayarlayıcı / alıcı yürütüldüğü sürece değişkene yalnızca gerçek iş parçacığı erişebilir.

İvar _internal özellikli bir mülkün MRC'si ile örnek:

[_internal lock]; //lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;

Yani bu son ikisi aynı:

@property(atomic, retain) UITextField *userName;

@property(retain) UITextField *userName; // defaults to atomic

Diğer yandan nonatomickodunuza hiçbir şey eklemez. Bu yüzden sadece güvenlik mekanizmasını kendiniz kodlarsanız iş parçacığı güvenlidir.

@property(nonatomic, retain) UITextField *userName;

Anahtar kelimelerin hiçbir şekilde ilk mülk özelliği olarak yazılması gerekmez.

Unutmayın, bu bir bütün olarak mülkün iş parçacığı için güvenli olduğu anlamına gelmez. Sadece ayarlayıcının / alıcının yöntem çağrısıdır. Ancak bir ayarlayıcı kullanırsanız ve bundan sonra 2 farklı iplikle aynı anda bir alıcı alırsanız, o da kırılabilir!


10

Başlamadan önce: Yeni bir yazarın gerçekleşmesi için bellekteki her nesnenin bellekten çıkarılması gerektiğini bilmelisiniz. Sadece kağıt üzerinde yaptığınız gibi bir şeyin üzerine yazamazsınız. Sen gerekir ilk (dealloc) silmeyi ya da daha sonra bunun üzerine yazabilirsiniz. Eğer silme işlemi tamamlanmışsa (ya da yarısı tamamlanmışsa) ve henüz hiçbir şey yazılmamışsa (ya da yarısı yazılmıştır) ve okumaya çalışıyorsanız çok sorunlu olabilir! Atomik ve atomik olmayan bu sorunu farklı şekillerde ele almanıza yardımcı olur.

Önce bu soruyu ve ardından Bbum'un cevabını okuyun . Ayrıca özetimi okuyun.


atomic DAİMA garanti eder

  • İki farklı kişi aynı anda okumak ve yazmak isterse, kağıdınız sadece yanmaz! -> Uygulamanız asla bir yarış durumunda bile çökmeyecek.
  • Bir kişi yazmaya çalışıyorsa ve yazmak için sadece 8 harfin 4'ünü yazdıysa, ortada hiç okuma yapamazsanız, okuma sadece 8 harfin tümü yazıldığında yapılabilir -> Okuma yok (al) gerçekleşir 'hala yazılan bir iş parçacığı', yani yazılacak 8 bayt bayt varsa ve yalnızca 4 bayt yazılırsa— o ana kadar, ondan okuma izniniz yoktur. O zamanlar çökmesine olmayacağını söyledi beri Ama bu değerinden okurdum autoreleased nesne.
  • Eğer daha önce yazmakta olan daha önce kağıt üzerinde yazılı ve sonra birisi okumak istediği edildiği o silinebilir olabilir hala okuyun. Nasıl? Mac OS Çöp Kutusu'na benzer bir şeyden okuyacaksınız (Çöp kutusu hala% 100 silinmediğinden ... bir limboda) ---> ThreadB zaten yazmak için ayrılmışken ThreadA okunacaksa, ThreadB tarafından yazılan son tam değerden bir değer veya otomatik kiralama havuzundan bir şey alın.

Saklama sayıları, Objective-C'de belleğin yönetilme şeklidir. Bir nesne oluşturduğunuzda, tutma sayısı 1 olur. Bir nesneye bir tutma mesajı gönderdiğinizde, tutma sayısı 1 artar. Bir nesneye bir yayın iletisi gönderdiğinizde, tutma sayısı 1 azalır. bir nesneye otomatik yayın mesajı gönderin, alıkonma sayısı gelecekte bir aşamada 1 azaltılır. Bir nesnenin alıkonma sayısı 0'a düşürülürse, yeniden konumlandırılır.

  • Atomic , iplik güvenliğini sağlamak için yararlı olmasına rağmen iplik güvenliğini garanti etmez . İş Parçacığı Güvenliği, kodunuzu nasıl yazdığınıza / okuduğunuz / yazdığınız iş parçacığı sırasına göredir. Sadece çizilemeyen çoklu iş parçacığını garanti eder.

Ne?! Çoklu kullanım ve iplik güvenliği farklı mıdır?

Evet. Birden çok iş parçacığı anlamına gelir: birden çok iş parçacığı paylaşılan bir veri parçasını aynı anda okuyabilir ve çökmeyeceğiz, ancak otomatik olarak yayınlanmayan bir değerden okumadığınızın garantisi yoktur. İplik güvenliği ile okuduğunuz şeyin otomatik olarak serbest bırakılmaması garanti edilir. Varsayılan olarak her şeyi atomik yapmamamızın nedeni, bir performans maliyeti olması ve çoğu şey için gerçekten iplik güvenliğine ihtiyaç duymamasıdır. Kodumuzun bir kısmı buna ihtiyaç duyar ve bu parçalar için kodumuzu kilitler, muteks veya senkronizasyon kullanarak güvenli bir şekilde yazmamız gerekir.


nonatomic

  • Mac OS Çöp Kutusu gibi bir şey olmadığından, hiç kimse her zaman bir değer elde edip etmediğinizi umursamaz (<- Bu, bir çökmeye yol açabilir) veya kimse yazınızın yarısını okumaya çalışırsa ( bellekte yarım yazma, kağıt üzerinde yarım yazmadan çok farklıdır, bellekte daha önce çılgın aptal bir değer verebilir, kağıt üzerinde yazılanların sadece yarısını görürsünüz) -> Çökmemeyi garanti etmez, çünkü otomatik serbest bırakma mekanizması kullanmaz.
  • Tam yazılı değerlerin okunacağını garanti etmez!
  • Atomdan daha hızlı

Genel olarak 2 açıdan farklıdırlar:

  • Otomatik kiralama havuzuna sahip olmanız veya olmamanız nedeniyle kilitleniyor veya kilitlenmiyor.

  • 'Henüz bitmemiş bir yazma veya boş değerin' ortasında okunmasına izin vermek veya izin vermemek ve yalnızca değer tam olarak yazıldığında okumaya izin vermek .


9

Mülkünüzü çok iş parçacıklı kodda kullanıyorsanız, atomik olmayan ve atomik öznitelikler arasındaki farkı görebilirsiniz. Nonatomik atomikten daha hızlıdır ve atomik atomik değil, iplik açısından güvenlidir.

Vijayendra Tripathi zaten çok iş parçacıklı bir ortama örnek oldu.


9
  • -Atomik, değişkenin (statik tip) yalnızca bir iş parçacığına eriştiği anlamına gelir.
  • -Atomik iplik korumalıdır.
  • -ama performans yavaş

Nasıl beyan edilir:

Atomik varsayılan olduğundan,

@property (retain) NSString *name;

VE uygulama dosyasında

self.name = @"sourov";

Üç özellikle ilgili bir görevin

 @property (retain) NSString *name;
 @property (retain) NSString *A;
 @property (retain) NSString *B;
 self.name = @"sourov";

Tüm özellikler paralel olarak çalışır (asenkron gibi).

A iş parçacığından "ad" çağırırsanız ,

Ve

Aynı zamanda

[self setName:@"Datta"]

B dişinden ,

Şimdi * adı mülkiyet nonatomic ise o zaman

  • A için "Datta" değerini döndürür
  • B için "Datta" değerini döndürür

Atomik olmayan iş parçacığı güvensiz denir, ancak paralel yürütme nedeniyle hızlı performans

Şimdi * name özelliği atomsa

  • A için "Sourov" değerini sağlayacaktır
  • Sonra B için "Datta" değerini döndürür

Bu yüzden atomik evre Güvenli olarak adlandırılır ve bu yüzden okuma-yazma güvenli olarak adlandırılır

Böyle bir durum işlemi seri olarak gerçekleştirilecektir. Ve Performansta Yavaş

- Nonatomik, değişkenin (dinamik tip) çoklu iş parçacığı erişimi anlamına gelir.

- Nonatomik iplik güvenli değildir.

- ancak performansta hızlı

-Nonatomik varsayılan davranış DEĞİLDİR, özellik özelliğine otomatik olmayan bir anahtar kelime eklememiz gerekir.

Swift için ObjC anlamda Swift özelliklerinin anatomik olmadığını doğrulamak. Bunun bir nedeni, özellik başına atomikliğin ihtiyaçlarınız için yeterli olup olmadığını düşünmenizdir.

Referans: https://forums.developer.apple.com/thread/25642

Daha fazla bilgi için lütfen web sitesini ziyaret edin http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html


4
Çok çok çok maaaaany Diğerleri söylediler, atomicbir DEĞİLDİR evreli! İplik sorunlarına karşı daha dayanıklıdır , ancak diş için güvenli değildir. Sadece tam bir değer, yani "doğru" bir değer (ikili seviye) elde etmenizi sağlar, ancak hiçbir şekilde iş mantığınız için mevcut ve "doğru" değer olmasını sağlamaz (geçmiş bir değer olabilir ve mantığınız tarafından geçersiz).
Alejandro Iván

6

Atomisite atomik (varsayılan)

Atomic varsayılan değerdir: hiçbir şey yazmazsanız mülkünüz atomiktir. Atomik bir özellik, ondan okumaya çalışırsanız, geçerli bir değer alacağınız garanti edilir. Bu değerin ne olabileceği konusunda herhangi bir garanti vermez, ancak sadece gereksiz hafızaya değil, iyi verileri geri alırsınız. Bu, tek bir değişkeni işaret eden birden çok iş parçacığına veya birden çok işleme sahipseniz, bir iş parçacığı okuyabilir ve başka bir iş parçacığı yazabilirse bunu yapmanıza izin verir. Aynı anda vururlarsa, okuyucu iş parçacığının iki değerden birini alması garanti edilir: değişiklikten önce veya değişiklikten sonra. Atomun size vermediği, bu değerlerden hangisini alabileceğiniz konusunda herhangi bir garanti. Atomic gerçekten yaygın olarak iş parçacığı açısından güvenli olmakla karıştırılır ve bu doğru değildir. İplik güvenliğinizi diğer yollarla garanti etmeniz gerekir.

nonatomic

Flip tarafında, atomik olmayan, tahmin edebileceğiniz gibi, sadece “o atomik şeyleri yapma” anlamına gelir. Kaybettiğiniz şey, her zaman bir şeyleri geri alabileceğinizin garantisidir. Bir yazının ortasında okumaya çalışırsanız, çöp verilerini geri alabilirsiniz. Ancak, diğer taraftan, biraz daha hızlı gidersiniz. Atomik özelliklerin bir değeri geri alacağınızı garanti etmek için biraz sihir yapması gerektiğinden, biraz daha yavaştırlar. Çok eriştiğiniz bir mülkse, bu hız cezasına maruz kalmamaya emin olmak için anatomik olmayana bırakmak isteyebilirsiniz. Giriş

nezaket https://academy.realm.io/posts/tmi-objective-c-property-attributes/

Atomisite özellik öznitelikleri (atomik ve atomik olmayan) karşılık gelen Swift özellik bildirimine yansıtılmaz, ancak ithal edilen özelliğe Swift'ten erişildiğinde Objective-C uygulamasının atomisite garantileri hala geçerlidir.

Öyleyse - Objective-C'de bir atomik özellik tanımlarsanız, Swift tarafından kullanıldığında atomik kalacaktır.

nezaket https://medium.com/@YogevSitton/atomic-vs-non-atomic-properties-crash-course-d11c23f4366c


5

Atomik özellik, üzerinde kaç tane işleyici ve ayarlayıcı yaptıklarından bağımsız olarak tamamen başlatılmış bir değerin korunmasını sağlar.

Atomik olmayan özellik, sentezlenen erişimcilerin aynı değeri farklı evrelerden aynı anda erişmesi durumunda ne olacağı konusunda hiçbir garanti vermeden doğrudan bir değer ayarladığını veya döndürdüğünü belirtir.


3

Atomik, değişkene aynı anda yalnızca bir iş parçacığının erişebileceği anlamına gelir (statik tip). Atomik iplik korumalıdır, ancak yavaştır.

Nonatomik, birden çok iş parçacığının değişkene aynı anda erişebileceği anlamına gelir (dinamik tip). Nonatomik iplik güvensizdir, ancak hızlıdır.


1

Atomik kullanıyorsanız, iş parçacığının güvenli ve salt okunur olacağı anlamına gelir. Otomatik olmayan kullanıyorsanız, çoklu iş parçacıkları değişkene erişir ve iş parçacığı güvensizdir, ancak hızlı yürütülür, okuma ve yazma işlemleri yapılır; bu dinamik bir tür.


1

Gerçek şu ki, atomik özelliği uygulamak için spin kilidi kullanıyorlar. Aşağıdaki gibi kod:

 static inline void reallySetProperty(id self, SEL _cmd, id newValue, 
      ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) 
    {
        id oldValue;
        id *slot = (id*) ((char*)self + offset);

        if (copy) {
            newValue = [newValue copyWithZone:NULL];
        } else if (mutableCopy) {
            newValue = [newValue mutableCopyWithZone:NULL];
        } else {
            if (*slot == newValue) return;
            newValue = objc_retain(newValue);
        }

        if (!atomic) {
            oldValue = *slot;
            *slot = newValue;
        } else {
            spin_lock_t *slotlock = &PropertyLocks[GOODHASH(slot)];
            _spin_lock(slotlock);
            oldValue = *slot;
            *slot = newValue;        
            _spin_unlock(slotlock);
        }

        objc_release(oldValue);
    }

0

Tüm karışıklığı basitleştirmek için mutex kilidini anlayalım.

Muteks kilidi, ada göre, nesnenin değişebilirliğini kilitler. Dolayısıyla, nesneye bir sınıf tarafından erişilirse, başka hiçbir sınıf aynı nesneye erişemez.

İOS yılında @sychroniseda FIFO modunda vermektedir ve akış aynı örneği paylaşan iki sınıf etkilenmez sağlar .Şimdi muteks kilidi sağlar. Ancak, görev ana iş parçacığındaysa, UI'nizi tutabileceği ve performansı düşürebileceği için atom özelliklerini kullanarak nesneye erişmekten kaçının.


-1

Atomik: İpliği NSLOCK kullanarak kilitleyerek iplik güvenliğini sağlayın.

Atomik olmayan: İplik kilitleme mekanizması olmadığından iplik güvenliğini sağlamaz.


-1

Atomik özellikler : - Atomik özelliğe atanmış bir değişken, yalnızca bir iş parçacığı erişimine sahip olduğu ve iş parçacığı güvenli olacağı ve performans açısından iyi olacağı anlamına gelirse, varsayılan davranışa sahip olacaktır.

Atomik Olmayan Özellikler : - Atomik özelliğe atanan bir değişken, çok iş parçacığı erişimine sahip olduğu ve iş parçacığı için güvenli olmayacağı ve performans açısından yavaş olacağı, varsayılan davranışa sahip olduğu ve iki farklı iş parçacığı aynı anda değişkene erişmek istediğinde anlamına gelir beklenmedik sonuçlar verecektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.