Atribut penyetel properti yang lemah dan kuat di Objective-C

94

Apa perbedaan antara atribut penyetel properti lemah dan kuat di Objective-C?

@property(retain, [weak/strong]) __attribute__((NSObject)) CFDictionaryRef myDictionary;

Apa dampak dan manfaatnya?

Saya mendengar bahwa weak tidak tersedia di iOS 4 dan kami perlu menggunakan assign.

Apakah lemah mirip dengan tugas?

kkurni
sumber

Jawaban:

102

Anda dapat mengaktifkan atau menonaktifkan ARC untuk file tertentu. Jika aktif, Anda tidak dapat menggunakan retain release autoreleasedll ... Sebagai gantinya Anda menggunakan strong weakuntuk properti atau __strong __weak untuk variabel (default ke __strong). Kuat sama dengan mempertahankan, namun ARC akan mengelola rilis untuk Anda.

Satu-satunya saat Anda ingin menggunakan weak, adalah jika Anda ingin menghindari siklus penahanan (misalnya, orang tua mempertahankan anak dan anak mempertahankan orang tua sehingga tidak ada yang pernah dilepaskan).

Bagian 'penghubung bebas pulsa' (casting dari NSke CF) agak sedikit rumit. Anda masih harus mengelola secara manual CFRelease()dan CFRetain()untuk objek CF. Ketika Anda mengubahnya kembali ke objek NS, Anda harus memberi tahu kompiler tentang jumlah retensi sehingga ia tahu apa yang telah Anda lakukan.

Semuanya ada di sini .

Robert
sumber
119

Berikut adalah informasi yang saya ketahui tentang properti variabel

  1. atomic // default
  2. nonatomik
  3. kuat = mempertahankan // default
  4. lemah
  5. menahan
  6. menetapkan // default
  7. unsafe_unretained
  8. menyalin
  9. hanya baca
  10. baca tulis // default

jadi di bawah ini adalah tautan artikel terperinci di mana Anda dapat menemukan semua atribut yang disebutkan di atas, yang pasti akan membantu Anda. Terima kasih banyak untuk semua orang yang memberikan jawaban terbaik di sini !!

Atribut atau Pengubah properti variabel di iOS

01. strong (iOS4 = pertahankan) - dikatakan "simpan ini di heap sampai saya tidak menunjuknya lagi" - dengan kata lain "Saya adalah pemiliknya, Anda tidak dapat membatalkan alokasi ini sebelum membidik dengan baik sama seperti mempertahankan "- Kamu menggunakan strong hanya jika kamu perlu mempertahankan objeknya. - Secara default, semua variabel instan dan variabel lokal adalah petunjuk yang kuat. - Kami umumnya menggunakan strong untuk UIViewControllers (orang tua item UI) - strong digunakan dengan ARC dan pada dasarnya membantu Anda, dengan tidak perlu khawatir tentang jumlah retensi objek. ARC secara otomatis melepaskannya untuk Anda setelah Anda selesai menggunakannya. Menggunakan kata kunci kuat berarti Anda memiliki objek tersebut.

Contoh:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

02. weak (iOS4 = unsafe_unretained) - dikatakan "simpan ini selama orang lain menunjukkannya dengan kuat" - hal yang sama seperti assign, no keep or release - Referensi "weak" adalah referensi yang tidak Anda simpan. - Kami biasanya menggunakan weak untuk IBOutlets (UIViewController's Childs). Ini berfungsi karena objek turunan hanya perlu ada selama objek induk memilikinya. - referensi lemah adalah referensi yang tidak melindungi objek yang direferensikan dari pengumpulan oleh pengumpul sampah. - Weak pada dasarnya adalah assign, sebuah properti yang tidak dipertahankan. Kecuali ketika objek dibatalkan alokasinya, pointer lemah secara otomatis disetel ke nol

Contoh:

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@synthesize myButton;

Jelaskan : Terima kasih kepada BJ Homer

Bayangkan objek kita adalah seekor anjing, dan anjing itu ingin melarikan diri (dicabut). Petunjuk yang kuat seperti tali pengikat pada anjing. Selama Anda memiliki tali pengikat yang terpasang pada anjing, anjing tidak akan lari. Jika lima orang memasang tali kekang pada satu anjing, (lima penunjuk kuat ke satu benda), maka anjing tidak akan lari sampai kelima tali dilepaskan. Petunjuk yang lemah, di sisi lain, seperti anak kecil yang menunjuk ke arah anjing dan berkata "Lihat! Seekor anjing!" Selama anjing masih terikat, anak-anak kecil masih bisa melihat anjing itu, dan mereka masih akan menunjuknya. Namun, segera setelah semua tali dilepaskan, anjing itu melarikan diri tidak peduli berapa banyak anak kecil yang menunjuknya. Segera setelah penunjuk kuat terakhir (tali) tidak lagi menunjuk ke suatu objek, objek tersebut akan dibatalkan alokasinya, dan semua penunjuk yang lemah akan dikosongkan. Kapan kita menggunakan weak? Satu-satunya saat Anda ingin menggunakan weak, adalah jika Anda ingin menghindari siklus penahanan (misalnya, orang tua mempertahankan anak dan anak mempertahankan orang tua sehingga tidak ada yang pernah dilepaskan).

swiftBoy
sumber
1
Dalam daftar awal, saya tidak begitu yakin apa yang Anda maksud dengan "default". Anda memiliki keduanya strong=retaindan assigndiberi label sebagai default, tetapi tidak boleh keduanya.
Slipp D. Thompson
27
Menikmati anjing di tali pengikat perbandingan. Menjelaskannya dengan cukup baik.
Jarrett Barnett
1
Penjelasan yang bagus, meski iOS tidak menggunakan pengumpulan sampah. ARC! = Pengumpulan sampah (!), Ini adalah teknologi yang berbeda.
1
weak dan unsafe_unretained berbeda (yang pertama menggunakan referensi lemah zero'ing, sedangkan yang terakhir melakukan squat)
wcochran
1
Saya hanya mempelajari iOS, tetapi tampaknya Anda salah menempatkan weakdan strongdalam contoh Anda. Bukankah lebih masuk akal bahwa orang tua memiliki strongreferensi ke anak-anaknya (sebagai myButtonproperti UIViewControllerkelas yang telah Anda tunjukkan weak) dan bahwa anak-anak menyimpan weakreferensi ke orang tuanya (seperti viewControllerproperti kelas anak yang Anda ' ve sebagai gantinya diatur ke strong). Misalnya, membaca Matt Neuburg, iOS 7 Programming Fundamentalsdia menunjukkan bahwa kelas yang menyatakan delegasinya sebagai properti akan membuatnya `lemah, itu tampaknya adil.
Bogdan Alexandru
2

Untuk menyebutkan bagian dari dokumen yang dirujuk oleh Robert yang menjawab dua pertanyaan terakhir Anda secara eksplisit:

// The following declaration is similar to "@property(assign) MyClass *myObject;"
// except that if the MyClass instance is deallocated,
// the property value is set to nil instead of remaining as a dangling pointer.
@property(weak) MyClass *myObject;

Ini disebut sebagai referensi lemah yang memusatkan perhatian. Anda dapat membuat referensi lemah yang tidak membidik referensi lemah menggunakan __unsafe_unretained, tetapi seperti yang tersirat dari namanya, hal ini umumnya tidak disarankan.

Juga di dokumen:

Weak references are not supported in Mac OS X v10.6 and iOS 4.
rimsky
sumber
1
Ya, ini benar, __unsafe_unretainedapakah versi ARC assign.
Robert
2

Penggunaan properti WEAK secara jelas adalah sebagai berikut:

Any control whose properties we need to change(eg:text of a label) is declared weak and as below:

@property(nonatomic,weak) IBOutlet Type *name;
Eg: @property(nonatomic,weak) IBOutlet UILabel *myLabel;
Alen Alexander
sumber
1
Menggunakan weak pada properti saya, saya mendapat peringatan yang mengatakan: "Receiver yang lemah mungkin disetel ke nihil secara tidak terduga". Saya telah melihat beberapa posting lain yang untuk mencegah peringatan ini, Anda harus membuat referensi lokal yang kuat. Dan jika ini benar, apa gunanya membuat properti menjadi lemah, jika pada akhirnya saya harus membuat referensi yang kuat?
arh
0

mari kita ambil contoh untuk menguraikan lebih lanjut (jawaban di atas sudah bagus), semoga contoh ini sedikit membantu

mari kita memiliki dua kelas A dan B.

//A.h

#import <Foundation/Foundation.h>
#import "B.h"

@interface A : NSObject

@property (nonatomic, strong) B *objB;

@end

@implementation A
//

@end

//B.h

    #import <Foundation/Foundation.h>
    #import "A.h"


    @interface B : NSObject

    @property strong text(nonatomic, strong) A *objA;

    @end

    @implementation B
    //

    @end

    and in main

    #import "B.h"
    #import "A.h"

    {
    A *obja =[[A alloc]init];
    B *objb =[[B alloc]init];
    A.objB=objb;
    B.objA=obja;
   }

kode di atas akan menghasilkan siklus retensi karena keduanya adalah tipe kuat a --------> b ---------> a

jadi untuk menghindarinya anda harus menggunakan property week salah satunya sehingga mingguan mengacu pada objek dan tidak menambah jumlah referensinya.

Anurag Bhakuni
sumber