Perbedaan antara kuat dan lemah dalam Objective-C

308

Saya baru mengenal Obj-C, jadi pertanyaan pertama saya adalah:

Apa perbedaan antara strongdan weakdalam @propertydeklarasi pointer ke objek?

Juga, apa nonatomicartinya?

Mark Pegasov
sumber
19
sebenarnya ini adalah pertanyaan yang bagus, kadang-kadang, kita lupa bagaimana konsep dasar dari preferensi kuat / lemah dan atom / nonatomik .... :) Terima kasih telah mengingatkan kami tentang hal itu ...
andikurnia
10
@JackyBoy Whats lucu adalah bahwa pencarian sederhana yang diusulkan di google membawa saya ke sini lol. #circularreference
Jason Renaldo
10
Saya cenderung tidak mempercayai banyak jawaban di google tetapi selalu merujuk pada SO untuk jawaban yang cerdas
JeffK

Jawaban:

642

Referensi yang kuat (yang akan Anda gunakan dalam kebanyakan kasus) berarti bahwa Anda ingin "memiliki" objek yang Anda referensikan dengan properti / variabel ini. Kompiler akan berhati-hati bahwa objek apa pun yang Anda tetapkan untuk properti ini tidak akan dihancurkan selama Anda mengarahkannya dengan referensi yang kuat. Hanya sekali Anda mengatur properti untuk nilobjek akan dihancurkan (kecuali satu atau lebih objek lain juga memiliki referensi yang kuat untuk itu).

Sebaliknya, dengan referensi yang lemah Anda menandakan bahwa Anda tidak ingin memiliki kontrol atas masa hidup objek. Objek yang Anda referensikan lemah hanya hidup karena setidaknya satu objek lain memiliki referensi yang kuat untuk itu. Setelah itu tidak lagi terjadi, objek dihancurkan dan properti lemah Anda akan secara otomatis diatur ke nil. Kasus penggunaan referensi lemah yang paling sering di iOS adalah:

  1. mendelegasikan properti, yang sering direferensikan dengan lemah untuk menghindari mempertahankan siklus, dan

  2. subview / kontrol tampilan utama pengontrol tampilan karena pandangan tersebut sudah sangat dipegang oleh tampilan utama.

atomik vs nonatomik mengacu pada keselamatan ulir metode pengambil dan penyetel yang disintesis kompiler untuk properti tersebut. atomic (default) memberitahu compiler untuk membuat metode accessor aman-benang (dengan menambahkan kunci sebelum ivar diakses) dan nonatomic melakukan yang sebaliknya. Keunggulan nonatomik adalah kinerja yang sedikit lebih tinggi. Di iOS, Apple menggunakan nonatomik untuk hampir semua properti mereka sehingga saran umum adalah agar Anda melakukan hal yang sama.

Ole Begemann
sumber
28
@ Borne: Itu tergantung pada apa yang Anda maksud dengan keamanan utas. atomicmenjamin bahwa properti dapat dibaca dan ditulis dengan aman dari beberapa utas secara bersamaan. Itu tidak berarti objek yang semua propertinya atomicaman secara otomatis.
Ole Begemann
3
Detail yang bagus. Saya pikir saya tidak benar-benar mendapatkannya sampai sekarang. Terima kasih.
ahmedalkaff
1
Sesuai dokumentasi apel, atomik dan nonatomik harus identik dengan keamanan utas. developer.apple.com/library/ios/documentation/cocoa/conceptual/…
Murtaza Khursheed Hussain
5
"Catatan: Atomicity properti tidak identik dengan keamanan utas objek." developer.apple.com/library/ios/documentation/cocoa/conceptual/…
GS
kenapa tidak kita hapus saja instance ketika kita tidak mau? Mengapa kita tidak bisa mengeluarkan udara dari balon atau menghancurkannya saat kita tidak mau, mengapa kita harus peduli dengan ikatan yang ada? Kami hanya butuh data.
Ashish Pisey
707

Mungkin bermanfaat untuk memikirkan referensi yang kuat dan lemah dalam hal balon.

Balon tidak akan terbang sejauh setidaknya satu orang memegang tali yang melekat padanya. Jumlah orang yang memegang string adalah jumlah yang dipertahankan. Ketika tidak ada yang memegang tali, ballon akan terbang menjauh (dealloc). Banyak orang dapat memiliki string ke balon yang sama. Anda bisa mendapatkan / mengatur properti dan memanggil metode pada objek referensi dengan referensi kuat dan lemah.

Referensi yang kuat adalah seperti berpegangan pada tali pada balon itu. Selama Anda memegang seutas tali yang melekat pada balon, itu tidak akan terbang.

Referensi yang lemah seperti melihat balon. Anda dapat melihatnya, mengakses propertinya, memanggil metode itu, tetapi Anda tidak memiliki string ke balon itu. Jika semua orang yang memegang tali melepaskannya, balon itu terbang, dan Anda tidak dapat mengaksesnya lagi.

MJN
sumber
68
+2 (kalau saja saya bisa). Serius, penjelasan yang sangat kreatif!
Con Antonakos
25
Setelah 1 setengah tahun pengembangan iOS, saya pikir barusan saya mengerti dengan jelas apa yang sebenarnya strongdan weakmaksudnya.
Isuru
17
@ X.Li Mempertahankan siklus seperti Anda memiliki 2 string ke ballon, salah satunya dimiliki oleh Anda (jadi Anda memiliki ballon ini), yang lain dimiliki oleh ballon (jadi ballon ini memiliki Anda). Karena Anda hanya memiliki akses ke string Anda, bagaimana Anda membiarkan ballon pergi jika ballon tidak mau pergi? Jadi lebih baik Anda memiliki ballon (kuat) sementara ballon tidak memiliki Anda (lemah). Ketika Anda ingin melepaskannya, cukup potong string :)
snakeninny
5
Baca profilnya, dia seorang instruktur iOS. Penjelasan yang sangat kreatif !! Angkat Topi :)
Hemang
3
Atom vs non-atom Saya pikir dapat digambarkan sebagai ruang toilet umum dengan beberapa pintu, dengan satu toilet di tengah. Begitu seseorang masuk ke toilet melalui satu pintu, dia mungkin juga mengunci semua pintu lainnya ke toilet jika dia tidak ingin mengalami momen canggung. Lol. Terima kasih telah membaca analogi omong kosong ini.
Chen Li Yong
24

kuat : memberikan nilai yang masuk ke dalamnya, itu akan mempertahankan nilai yang masuk dan melepaskan nilai yang ada dari variabel instan

lemah : akan menetapkan nilai yang masuk tanpa mempertahankannya.

Jadi perbedaan dasarnya adalah mempertahankan variabel baru. Secara umum Anda ingin mempertahankannya tetapi ada situasi di mana Anda tidak ingin memilikinya jika tidak, Anda akan mendapatkan siklus penyimpanan dan tidak dapat membebaskan memori objek. Misalnya. obj1 mempertahankan obj2 dan obj2 mempertahankan obj1. Untuk mengatasi situasi seperti ini Anda menggunakan referensi yang lemah.

Pfitz
sumber
12

Jawaban bodoh: -

Saya pikir penjelasan diberikan dalam jawaban di atas, jadi saya hanya akan memberi tahu Anda di mana harus menggunakan STRONGdan di mana harus digunakan WEAK:

Penggunaan Weak: - 1. Delegasi 2. Outlet 3. Subview 4. Kontrol, dll.

Penggunaan Strong: - Tersisa di mana saja yang tidak termasuk dalam WEAK.

shubham mishra
sumber
2
Dan apa yang mengandung dll: P
Rajneesh071
3
webView, mapView, dll
shubham mishra
4
sebenarnya sebagian besar subview yang kita seret dan lepas di storyboard
shubham mishra
8

kuat dan lemah , kata kunci ini berkisar di sekitar Kepemilikan Objek di Objective-C

Apa yang dimaksud dengan kepemilikan objek?

Variabel pointer menyiratkan kepemilikan objek yang mereka tunjuk.

  • Ketika suatu metode (atau fungsi) memiliki variabel lokal yang menunjuk ke suatu objek, variabel itu dikatakan memiliki objek yang ditunjuk.
  • Ketika suatu objek memiliki variabel instan yang menunjuk ke objek lain, objek dengan pointer dikatakan memiliki objek yang ditunjuk.

Kapan saja variabel pointer menunjuk ke suatu objek, objek itu memiliki pemilik dan akan tetap hidup. Ini dikenal sebagai referensi yang kuat .

Suatu variabel dapat secara opsional tidak mengambil kepemilikan atas suatu objek yang ditunjuknya. Variabel yang tidak memiliki kepemilikan atas suatu objek dikenal sebagai referensi yang lemah .

Lihat penjelasan rinci di sini Demystifying @property dan atribut

Vinay Jain
sumber
6

Di sini, Dokumentasi Apple telah menjelaskan perbedaan antara properti lemah dan kuat menggunakan berbagai contoh:

https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW3

Di sini, Di blog ini penulis telah mengumpulkan semua properti di tempat yang sama. Ini akan membantu untuk membandingkan karakteristik properti:

http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html

Subhash Kumar Singh
sumber
6

kuat adalah default. Objek tetap "hidup" selama ada pointer kuat untuk itu.

lemah menentukan referensi yang tidak membuat objek yang dirujuk tetap hidup. Referensi yang lemah diatur ke nol ketika tidak ada referensi yang kuat ke objek.

Ankit Vyas
sumber
2

Untuk memahami referensi Strong dan Lemah, perhatikan contoh di bawah ini, misalkan kita memiliki metode yang dinamai displayLocalVariable.

 -(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
  }

Dalam ruang lingkup metode di atas variabel myView terbatas pada metode displayLocalVariable, setelah metode selesai variabel myView yang memegang objek UIView akan mendapatkan deallocated dari memori.

Sekarang bagaimana jika kita ingin memegang variabel myView sepanjang siklus hidup pengontrol tampilan kita. Untuk ini kita dapat membuat properti bernama usernameView yang akan memiliki referensi kuat ke variabel myView (lihat @property(nonatomic,strong) UIView* usernameView;dan self.usernameView = myView;dalam kode di bawah), seperti di bawah ini,

@interface LoginViewController ()

@property(nonatomic,strong) UIView* usernameView;
@property(nonatomic,weak) UIView* dummyNameView;

- (void)displayLocalVariable;

@end

@implementation LoginViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

}

-(void)viewWillAppear:(BOOL)animated
{
     [self displayLocalVariable];
}

- (void)displayLocalVariable
{
   UIView* myView = [[UIView alloc] init];
   NSLog(@"myView tag is = %ld", myView.tag);
   self.usernameView = myView;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}


@end

Sekarang dalam kode di atas Anda dapat melihat myView telah ditetapkan untuk self.usernameView dan self.usernameView memiliki referensi yang kuat (seperti yang kami nyatakan dalam antarmuka menggunakan @property) ke myView. Karenanya myView tidak akan dibatalkan alokasi dari memori sampai self.usernameView hidup.

  • Referensi yang lemah

Sekarang pertimbangkan untuk menetapkan myName ke dummyNameView yang merupakan referensi Lemah, self.dummyNameView = myView;Tidak seperti referensi Kuat Lemah akan memegang myView hanya sampai ada referensi kuat untuk myView. Lihat kode di bawah ini untuk memahami referensi Lemah,

-(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
     self.dummyNameView = myView;
  }

Dalam kode di atas ada referensi Lemah untuk myView (yaitu self.dummyNameView memiliki referensi Lemah untuk myView) tetapi tidak ada referensi Kuat untuk myView, maka self.dummyNameView tidak akan dapat memegang nilai myView.

Sekarang pertimbangkan lagi kode di bawah ini,

-(void)displayLocalVariable
      {
         UIView* myView = [[UIView alloc] init];
         NSLog(@"myView tag is = %ld", myView.tag);
         self.usernameView = myView;
         self.dummyNameView = myView;
      } 

Dalam kode di atas self.usernameView memiliki referensi Strong ke myView, maka self.dummyNameView sekarang akan memiliki nilai myView bahkan setelah metode berakhir karena myView memiliki referensi Strong yang terkait dengannya.

Sekarang setiap kali kita membuat referensi Strong ke suatu variabel, jumlah retainnya dapat bertambah satu dan variabel itu tidak akan dideallocated sampai jumlah retainnya mencapai 0.

Semoga ini membantu.

Mahadev Mandale
sumber
2019-07-25 12: 33: 15.479002 + 0530 StrongAndWeak [6329: 245483] Nama saya = ABC 2019-07-25 12: 33: 15.479226 + 0530 StrongAndWeak [6329: 245483] Nama saya untuk strong = ABC 2019- 07-25 12: 33: 15.479418 + 0530 StrongAndWeak [6329: 245483] Nama saya untuk lemah = ABC dalam hal ini Anda memberi tahu properti lemah tidak memiliki nilai nama saya. Tetapi saya mendapatkan nilai nama saya sebagai ABC untuk kedua referensi .. ..? bisakah Anda memberikan jawaban yang lebih jelas .... Terima kasih sebelumnya
Madhu_Nani
@Raviteja_DevObal ARC tidak berjanji untuk segera melakukannya (yaitu membatalkan alokasi string @ "ABC"), tetapi itu akan mendapatkan deallocate pasti nanti ...
Mahadev Mandale
@Raviteja_DevObal Seperti Jelaskan di sini string adalah contoh yang buruk untuk ini. Saya telah memperbarui jawaban saya dengan objek UIView, semoga membantu.
Mahadev Mandale
1

Kuat : Pada dasarnya Digunakan Dengan Properti yang kami gunakan untuk mendapatkan atau mengirim data dari / ke kelas lain. Lemah : Biasanya semua outlet, koneksi dari jenis Lemah dari Antarmuka.

Nonatomik : Jenis properti seperti itu digunakan dalam kondisi ketika kita tidak ingin membagikan outlet atau objek kita ke dalam Threads simultan yang berbeda. Dengan kata lain, instance Nonatomic membuat properti kami untuk berurusan dengan satu utas pada satu waktu. Semoga bermanfaat bagi Anda.

Joga singh
sumber