Soru Atomik ve atom dışı özellikler arasındaki fark nedir?


Ne yapar atomic ve nonatomic mülk beyannameleri demek?

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

Bu üç arasındaki operasyonel fark nedir?


1723
2018-02-26 02:31


Menşei


developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/... - KKendall
@Alex Wayne - bir sorunum var ve onu yayınladım ama kimse bunun için cevap vermedi. Bunun için bana yardım edebilir misin? Soru Bağlantısı - stackoverflow.com/questions/35769368/... - DJ1


Cevaplar:


Son ikisi aynıdır; "atomik" varsayılan davranıştır (aslında bir anahtar kelime olmadığını unutmayın; sadece yokluğu ile belirtilir nonatomic - atomic llvm / clang'ın son sürümlerinde bir anahtar kelime olarak eklendi).

Yöntem uygulamalarının @ sentezlendiğini varsayarsak, atomik olmayan atomik olmayanlar üretilen kodu değiştirir. Kendi düzenleyici / alıcılarınızı yazıyorsanız, atomik / nonatomik / tutma / atama / kopyalama sadece tavsiye niteliğindedir. (Not: @synthesize şimdi LLVM'nin son sürümlerinde varsayılan davranıştır.Örnek değişkenlerini bildirmeye de gerek yoktur, onlar da otomatik olarak sentezlenecek ve _ yanlışlıkla doğrudan erişimi önlemek için adlarına hazırlanmıştır).

"Atomik" ile, sentezlenmiş dizici / alıcı, bir bütün Değer her zaman başka bir iş parçacığındaki ayarlayıcı etkinliğine bakılmaksızın, getterden döndürülür veya setter tarafından ayarlanır. Diğer bir deyişle, eğer iplik A, ayarlayıcıyı çağırırsa, eğer iplik A, ayarlayıcının ortasına gelirse, gerçekte geçerli bir değer - büyük olasılıkla, otomatik olarak aktive edilen bir nesne - arayan A'ya çağrılacaktır.

İçinde nonatomicböyle bir garanti verilmez. Böylece, nonatomic "atomik" den çok daha hızlıdır.

Ne "atomik" yapar değil iplik güvenliği ile ilgili herhangi bir garanti vermek. Eğer A iş parçacığı, alıcıyı farklı değerlerle çağıran B ve C iş parçacığı ile eşzamanlı olarak çağırıyorsa, iş parçacığı, döndürülen üç değerden herhangi birini alabilir - herhangi bir ayarlayıcıdan önce çağrılan veya ayarlayıcılara geçirilen değerlerden biri B ve C'de, aynı şekilde, nesne, B veya C değerinden, sonuç vermeyecek şekilde sonuçlanabilir.

Veri bütünlüğünün sağlanması - çok iş parçacıklı programlamanın temel sorunlarından biri - başka yollarla elde edilir.

Buna ekleniyor:

atomicity Tek bir özelliğin özelliği, birden fazla bağımlı özellikte olduğunda iplik 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ığı arayarak nesneyi yeniden adlandırma olabilir setFirstName: ve sonra arayarak setLastName:. Bu arada, iplik B arayabilir fullName A iş parçacığı arasında iki çağrı ve eski soyadı ile birleştiğinde yeni ad alırsınız.

Bunu ele almak için bir işlem modeli. Yani erişimin dışarıda bırakılmasına izin veren başka türde bir senkronizasyon ve / veya dışlama fullName bağımlı özellikler güncellenirken.


1668
2018-02-26 06:40



Herhangi bir iş parçacığı güvenli kod kendi kilitleme vb yapıyor olacak, ne zaman atomik özellik erişimcileri kullanmak istersiniz? İyi bir örnek düşünürken sorun yaşıyorum. - Daniel Dickison
@bbum Anlamlıdır. Yorumunuzu başka bir cevaba sevdim, iş parçacığı güvenliği daha fazla model düzeyinde bir endişe. IBM iş parçacığı güvenlik tanımından: ibm.co/yTEbjY “Eğer bir sınıf doğru bir şekilde uygulanmışsa, bu da onun spesifikasyonuna uygun olduğunu söylemenin başka bir yoludur, o sınıfın nesnelerinin üzerine herhangi bir işlem dizisi (kamu alanlarının okunması ya da yazılması ve kamu yöntemlerine çağrı yapılması) nesneyi yerleştirebilmelidir. Geçersiz bir duruma, nesnenin geçersiz bir durumda olduğunu gözlemleyin veya sınıfın değişmezlerini, önkoşullarını veya posta koşullarını ihlal edin. " - Ben Flynn
İşte @StevenKramer 's benzer bir örnek: Benim bir @property NSArray* astronomicalEvents; UI'de görüntülemek istediğim verileri listeler. Uygulama işaretçi noktalarını boş bir diziye başlattığında, uygulama web'den veri çeker. 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. Bu iş parçacığı güvenli ve bir şey kaçırmadığım sürece herhangi bir kilitleme kodu yazmak zorunda değildim. Bana oldukça yararlı geliyor. - bugloaf
@HotLicks Bir başka eğlenceli olan; belirli mimarilerde (hangisi olduğunu hatırlayamaz), bir argüman olarak geçen 64 bit değerler, bir kayıttaki yarısına ve yığının yarısına kadar iletilebilir. atomic Çapraz iplik yarı değerli okumaları engeller. (İzlemek için eğlenceli bir hataydı.) - bbum
@congliu Thread A, olmadan bir nesneyi döndürür retain/autorelease dans. İş parçacığı B nesnesi. A iş parçacığı gider Boom. atomic A iş parçacığının dönüş değeri için güçlü bir başvuru (+1 tutma sayısı) olmasını sağlar. - bbum


Bu Apple’da açıklanmaktadır. belgelemeama aşağıda gerçekte neler olduğuna dair bazı örnekler. "Atomik" anahtar kelime olmadığını, "nonatomic" belirtmezseniz, özellik atomik olduğunu, ancak "atomik" ifadesini açıkça belirterek bir hataya neden olacağını unutmayın.

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

- (UITextField *) userName {
    return userName;
}

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

Şimdi, atom 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 versiyon, iplik güvenliğini sağlamak için bir kilit almak zorundadır ve aynı zamanda nesnenin ref sayımını (ve bunu dengelemek için otomatik döndürme sayısını) çarpmak zorundadır, böylece nesnenin arayan için var olması garanti edilir, aksi halde Başka bir iş parçacığı değeri ayarlıyorsa, ref sayısının 0'a düşmesine neden olursa potansiyel bir yarış durumu.

Aslında, bu özelliklerin özelliklerin skaler değerler veya nesneler olup olmadığına ve nasıl korunacağına, kopyalanmayacağına, salt nonatomik, vb. Etkileşime bağlı olarak nasıl çalıştığına dair çok sayıda farklı varyant vardır. Genel olarak mülk sentezleyicileri, tüm kombinasyonlar için "doğru şeyi" nasıl yapacağını bilir.


342
2018-02-26 06:24



Kilit, "iplik güvenliğini garanti etmiyor" değil. - Jonathan Sterling
@Louis Gerbarg: Aynı nesneyi (yani: userName == userName_) atamaya çalıştığınızda (nonatomic, retain) setter sürümünüzün düzgün çalışmayacağına inanıyorum. - Florin
Kodunuz biraz yanıltıcıdır; var yok hayır atomik alıcı / ayarlayıcıların senkronize edildiğini garanti eder. kritik olarak,@property (assign) id delegate; hiçbir şeyde senkronize edilmiyor (iOS SDK GCC 4.2 ARM -Os), yani arasında bir yarış var demektir [self.delegate delegateMethod:self]; ve foo.delegate = nil; self.foo = nil; [super dealloc];. Görmek stackoverflow.com/questions/917884/... - tc.
@fyolnish Ne olduğundan emin değilim _val/val ama hayır, gerçekten değil. Bir atomik için alıcı copy/retain özellik, ayarlayıcının başka bir iş parçacığında çağrılması nedeniyle geri sayımı sıfır olan bir nesneyi döndürmemesini sağlamalıdır. Bu, esasen ivar'ı okuması gerektiği anlamına gelir; ve sonra korumayı dengelemek için otomatikleştirin. Bu aslında anlamına gelir her ikisi de alıcı ve ayarlayıcı bir kilidi kullanmak zorundadır (bellek düzeni düzeltildiyse CAS2 talimatları ile yapılmalıdır; -retain bir yöntem çağrısıdır. - tc.
@tc Oldukça uzun bir zaman oldu ama yazmayı kastettiğim şey muhtemelen şunlardı: gist.github.com/fjolnir/5d96b3272c6255f6baae Ancak evet, eski değerin bir okuyucu tarafından setFoo'dan önce okunması mümkündür: geri dönüyor ve okuyucu döndürmeden önce yayınlanıyor. Ama belki de setter -aease yerine -autorelease kullandıysa, bunu düzeltirdi. - Fjölnir


atomik

  • varsayılan davranış
  • Başka bir işlem değişkene erişmeden önce, mevcut işlemin CPU tarafından tamamlanmasını sağlar.
  • sürecin tamamlandığını garanti ettiği için hızlı değil

Sigara Atom

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

148
2018-05-25 10:56





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

"Name" adında bir atom dizesi özelliği olduğunu varsayalım ve eğer çağırırsanız [self setName:@"A"] A iş parçacığından [self setName:@"B"] B parçasından ve ara [self name] C dişinden sonra, farklı ipliklerdeki tüm işlemler seri olarak gerçekleştirilir, yani eğer bir iplik bir ayarlayıcıyı veya alıcıyı çalıştırıyorsa, diğer dişler bekler.

Bu, "isim" özelliğini okuma / yazma güvenli yapar, ancak başka bir iş parçacığı, D, çağrıları [name release] eşzamanlı olarak bu işlem burada bir setter / getter çağrısı olmadığı için bir çarpışma oluşturabilir. Bir nesne okuduğundan / yazdığından (ATOMIC) değil, başka bir iş parçacığı eşzamanlı olarak nesneye her tür ileti gönderebildiğinden, iş parçacığı güvenli değil demektir. Geliştirici, bu tür nesneler için iplik güvenliğini sağlamalıdır.

Eğer "isim" adı nonatomik değilse, o zaman yukarıdaki örnekte - A, B, C ve D tüm öngörülemeyen sonuçları üreten eşzamanlı olarak yürütülür. Atomik durumunda, A, B veya C'den herhangi biri ilk önce yürütülür, ancak D hala paralel olarak yürütülebilmektedir.


125
2018-01-31 18:36





Sözdizimi ve anlambilim, bu soruya verilen diğer mükemmel cevaplarla zaten iyi tanımlanmıştır. Çünkü icra ve performans iyi değil, cevabımı ekleyeceğim.

Bu 3 arasındaki fonksiyonel fark nedir?

Her zaman atomik bir varsayılan olarak oldukça merak ettim. Çalıştığımız soyutlama seviyesinde,% 100 iplik güvenliği elde etmek için bir araç olarak bir sınıfın atomik özelliklerini kullanarak bir köşe davasıdır. Gerçekten doğru çoklu iş parçacıklı programlar için, programlayıcının müdahalesi neredeyse kesinlikle bir gerekliliktir. Bu arada, performans özellikleri ve icra henüz ayrıntılı olarak detaylandırılmamıştır. Yıllar boyunca çok fazla iş parçacıklı program yazmış olmama rağmen, mülklerimi bildiriyordum. nonatomictüm zaman boyunca atomik herhangi bir amaç için duyarlı değildi. Atomik ve atomik olmayan özelliklerin ayrıntıları tartışılırken bu soruBazı profilleme meraklı sonuçlar ile karşılaştı.

infaz

Tamam. Temizlemek istediğim ilk şey, kilitleme uygulamasının uygulama tanımlı ve soyutlanmış olmasıdır. Louis kullanıyor @synchronized(self) onun örneğinde - bunu ortak bir karışıklık kaynağı olarak görmüştüm. Uygulama değil aslında kullanım @synchronized(self); nesne seviyesini kullanır döner kilitler. Louis'in illüstrasyonu, hepimizin aşina olduğu yapıları kullanarak üst düzey bir illüstrasyon için iyidir, ancak kullanılmadığını bilmek önemlidir @synchronized(self).

Diğer bir fark, atomik özelliklerin, nesnelerinizi alıcı içindeki döngüde tutacağı / bırakacağıdır.

performans

İşte ilginç kısmı: Atomik özellik erişimini kullanarak performans tek adaylı (örneğin, tek-dişli) vakalar, bazı durumlarda gerçekten çok hızlı olabilir. İdeal vakalardan daha azında, atomik girişlerin kullanımı 20 kattan fazla maliyete mal olabilir. nonatomic. İken tartışmalı 7 iplik kullanan olgu üç baytlı yapı için 44 kat daha yavaştı (2.2 GHz core i7 Dört Çekirdekli, x86_64). Üç bayt yapı, çok yavaş bir özellik örneğidir.

İlginç yan not: Üç bayt yapının kullanıcı tanımlı erişimcileri, sentezlenmiş atomik erişim sağlayıcılardan 52 kat daha hızlıydı; veya sentezlenen atom olmayan erişim hızının% 84'ü.

İtiraz edilen davalardaki nesneler de 50 kez geçebilir.

Uygulamalardaki optimizasyonların ve varyasyonların sayısından dolayı, bu bağlamlardaki gerçek dünya etkilerini ölçmek oldukça zordur. Sık sık "Güvenle, profilini koymadıkça ve bir sorun olduğunu farketmezsen" gibi bir şey duyabilirsiniz. Soyutlama seviyesinden dolayı, gerçek etkiyi ölçmek gerçekten çok zordur. Profillerden kaynaklanan gerçek maliyetlerin azaltılması çok zaman alıcı olabilir ve soyutlamalar nedeniyle oldukça hatalı olabilir. Ayrıca, ARC ve MRC büyük bir fark yaratabilir.

O zaman geri çekilelim değil Mülk erişimlerinin uygulanmasına odaklanarak, objc_msgSendve birçok arama için bazı gerçek dünyadaki yüksek düzey sonuçları incelemek NSString aldatıcı tek adaylı vakalar (saniye cinsinden değerler):

  • MRC | nonatomik | el ile uygulanmış alıcılar: 2
  • MRC | nonatomik | sentezlenmiş alıcı: 7
  • MRC | atomik | sentezlenmiş alıcı: 47
  • ARC | nonatomik | sentezlenmiş getter: 38 (not: ARC'nin ref sayısını ekleyerek burada bisiklete binme)
  • ARC | atomik | sentezlenmiş alıcı: 47

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

Her ne kadar performansa dikkat etsem de, hala söylüyorum Semantik İlk!. Bu arada, birçok proje için performans 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, birkaç saatlik karşılaştırmayı kaydeder ve programlarınızı tasarlarken daha bilinçli bir karar vermenize yardımcı olur.


108
2017-08-18 09:47



MRC | atomik | sentezlenen alıcı: 47 ARC | atomik | sentezlenmiş getter: 47 Onları aynı yapan nedir? ARC'nin daha fazla yükü yok mu? - SDEZero
Yani atomik özellikler kötü ise, varsayılan değerlerdir. Boilerplate kodunu artırmak için? - Kunal Balani
@ LearnCocos2D Sadece 10.8.5 üzerinde aynı makinede test ettim, 10.8'i hedefleyerek, tek işlenmemiş, tartışmasız dava için NSString ölümsüz olmayan: -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ı. Ben hiç yapmıyordum @synchronized karşılaştırmaları. @synchronized Semantik olarak farklıdır ve eşzamanlı olmayan eşzamanlı programlarınız varsa bunu iyi bir araç olarak görmüyorum. hıza ihtiyacınız varsa, kaçının @synchronized. - justin
Bu testi bir yerde çevrimiçi var mı? Benimkini buraya eklemeye devam ediyorum: github.com/LearnCocos2D/LearnCocos2D/tree/master/... - LearnCocos2D
@ LearnCocos2D İnsan tüketimine hazırlanmadım, üzgünüm. - justin


atomik= iplik güvenliği

Sigara atom = İplik güvenliği yok

İplik güvenliği:

Örnek değişkenleri, birden çok iş parçacığından erişildiğinde doğru şekilde davranırlarsa, çalışma zaman ortamına göre bu iş parçacıklarının yürütülmesinin zamanlamasını veya araya sokulmasından bağımsız olarak ve arama kodunun ek bir eşzamanlaması veya başka bir koordinasyonu olmadan iş parçacığı güvenlidir.

Bizim bağlamımızda:

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

Nerede kullanılır? atomic:

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

Uygulanması atomic:

Kadar hızlı değil nonatomic Çünkü nonatomic çalışma zamanından herhangi bir watchdog çalışması gerektirmez.

Nerede kullanılır? nonatomic:

Örnek değişkeni birden çok ileti dizisi tarafından değiştirilmeyecekse, bunu kullanabilirsiniz. Performansı arttırır.


89
2017-07-10 13:07



Burada söylediğin her şey doğru, ama son cümle bugünün programlaması için esas olarak "yanlış", Dura. Bu şekilde "performansı artırmaya" çalışmak için uğraşacağınız gerçekten düşünülemez. (Demek istediğim, bunun ışığının içine girmeden önce, "ARC kullanmıyor", "NSString kullanmıyor, çünkü yavaştır" diyeceksin.) Aşırı bir örnek vermek gerekirse, "takım, Bizi aşağı doğru yavaşlattığı için, herhangi bir yorum koymayın. " Güvenilmezlik adına (varolmayan) teorik performans kazanımlarını isteyeceğiniz gerçekçi bir geliştirme boru hattı yoktur. - Fattie
@JoeBlow bir gerçeği burada doğrulayabilirsiniz developer.apple.com/library/mac/documentation/Cocoa/Conceptual/... - Durai Amuthan.H
Güzel açıkladı (y) - Sunil Targe


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

'atomik', parçalanamayacağı anlamına gelir.   OS / programlama terimlerinde atomik işlev çağrısı kesilemeyen bir işlevdir - tüm işlev yürütülmeli ve tamamlanana kadar OS'nin olağan bağlamında geçiş yapılarak CPU'dan çıkarılmalıdır. Sadece bilmediğiniz durumda: CPU her seferinde sadece bir şey yapabildiğinden, işletim sistemi CPU'ya tüm çalışan işlemlere küçük zaman dilimlerinde erişmesini sağlar. yanılsama çoklu görev CPU zamanlayıcı, bir işlemin yürütülmesinin herhangi bir noktasında (orta işlev çağrısında bile) kesintiye uğratabilir (ve bunu yapar). Bu nedenle, iki sürecin, değişkeni aynı anda güncellemeye çalıştığı paylaşılan sayaç değişkenlerini güncelleme gibi eylemler için, "atomik olarak" yürütülmesi gerekir, yani, her güncelleme eylemi, başka bir işlemin üzerine başka herhangi bir işlemin taklit edilmesinden önce tamamlanmalıdır. İŞLEMCİ.

Bu durumda atomun, öznitelik okuyucu yöntemlerinin kesintiye uğratılabileceği anlamına geleceğini tahmin ediyorum - aslında, başka bir iş parçacığı / çağrı / işlev aldığından, yöntem tarafından okunan değişken (ler) in değerinin yarısını değiştiremeyeceği anlamına gelir. CPU üzerinde değiştirildi.

Çünkü atomic değişkenler kesintiye uğramamakta, herhangi bir noktada içerdikleri değer (thread-lock) olması garantilidir bozulmamışBununla birlikte, bu iplik kilidinin bunlara daha yavaş erişmesini sağlamak. non-atomic Öte yandan değişkenler böyle bir garanti vermezler ancak daha hızlı erişim lüksünü sunarlar. Özetlemek için ile devam edin non-atomic Değişkenlerinizin aynı anda birden fazla iş parçacığı tarafından erişilemeyeceğini ve bir şeyleri hızlandıracağını unutmayın.


67
2018-02-24 05:17





Çok fazla makale okuduktan sonra, Stack Overflow gönderileri ve değişken özellik niteliklerini kontrol etmek için demo uygulamalar yaptıktan sonra, tüm öznitelik 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

Makalede İOS'ta değişken özellik özellikleri veya değiştiriciler Yukarıda belirtilen tüm nitelikleri bulabilirsiniz ve bu kesinlikle size yardımcı olacaktır.

  1. atomic

    • atomic sadece bir iş parçacığı değişkene (statik tip) erişir.
    • atomic iş parçacığı güvenlidir.
    • Ancak performansta yavaştır
    • atomic varsayılan davranış
    • Çöp almayan bir çevrede bulunan atomik erişim sağlayıcıları (yani, tutma / bırakma / otomatik kaldırma kullanırken), başka bir iş parçacığının değerin doğru ayarlanması / ayarlanması ile etkileşime girmediğinden emin olmak için bir kilit kullanacaktır.
    • Bu aslında bir anahtar kelime değildir.
       

    Örnek:

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

    • nonatomic Değişken (dinamik tip) çoklu iş parçacığı erişim anlamına gelir.
    • nonatomic iş parçacığı güvenli değil.
    • Ancak performansta hızlıdır
    • nonatomic varsayılan davranış değil. Eklemek gerekiyor nonatomic özellikteki anahtar kelime.
    • İki farklı işlemin (thread) aynı anda aynı değişkene erişmesi beklenmedik davranışlarla sonuçlanabilir.
       

    Örnek:

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

61
2018-03-21 07:10



Her ikisi de atama ve güçlü / bekletme nasıl varsayılan olabilir? - BangOperator
ARC ile güçlü gelir, ARC'den önce varsayılan değer korunur - abdullahselek