Atomik ve atomik olmayan nitelikler arasındaki fark nedir?

Özellik bildirimlerinde atomic ve nonatomic ne anlama gelir?

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

Bu üçü arasındaki operasyonel fark nedir?

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

"atomic" anahtar kelimesinin olmadığını unutmayın, "nonatomic" belirtmezseniz, özellik atomiktir, ancak "atomic" açıkça belirtmek bir hataya neden olur.

Eğer "nonatomic" belirtmezseniz, özellik atomik olur, ancak isterseniz son sürümlerde "atomic" 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 sürüm iş parçacığı güvenliğini garanti etmek için bir kilit almak zorundadır ve ayrıca nesne üzerindeki ref sayısını (ve bunu dengelemek için otomatik serbest bırakma sayısını) artırır, böylece nesnenin arayan için var olduğu garanti edilir, aksi takdirde başka bir iş parçacığı değeri ayarlıyorsa potansiyel bir yarış koşulu vardır ve ref sayısının 0'a düşmesine neden olur.

Aslında, özelliklerin skaler değerler mi yoksa nesneler mi olduğuna ve tutma, kopyalama, salt okunur, atomik olmayan vb. etkileşimlere bağlı olarak bu şeylerin nasıl çalıştığına dair çok sayıda farklı varyant vardır. Genel olarak özellik sentezleyicileri tüm kombinasyonlar için "doğru şeyi" nasıl yapacaklarını bilirler.

Yorumlar (7)

Atomik :

Atomic, özelliğe 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 bir özelliğin get/set işlemi, bir başkası ona erişmeden önce tamamlanmalıdır.

Aşağıdaki işlevin aynı anda iki iş parçacığı üzerinde gerçekleştiğini hayal ederseniz, sonuçların neden hoş olmayacağı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 döndürülmesi, çoklu iş parçacığı durumunda en iyi seçim olmasını sağlar.

Eksiler : Performans darbesi, yürütmeyi biraz daha yavaşlatır

Atomik Olmayan :

Atomic'in aksine, her seferinde tamamen başlatılmış nesne dönüşü sağlamaz.

Artılar : Son derece hızlı uygulama.

Eksiler : Çoklu iş parçacığı durumunda çöp değeri olasılığı.

Yorumlar (1)

Ö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 atomik erişimciler (yani tutma/serbest bırakma/otor serbest bırakma kullanıldığında), başka bir iş parçacığının değerin doğru ayarlanmasına/alınmasına müdahale etmemesini sağlamak için bir kilit kullanacaktır.

Daha fazla bilgi ve çok iş parçacıklı uygulamalar oluştururken dikkat edilmesi gereken diğer hususlar için Apple Objective-C 2.0 belgelerinin "Performance and Threading" bölümüne bakın.

Yorumlar (2)