Pertanyaan Apakah ada perbedaan antara "variabel instan" dan "properti" di Objective-c?


Apakah ada perbedaan antara "variabel instan" dan "properti" di Objective-c?

Saya tidak terlalu yakin tentang ini. Saya pikir bahwa "properti" adalah variabel instan yang memiliki metode pengakses, tetapi saya mungkin berpikir salah.


76
2018-05-09 16:53


asal


Jawaban:


Properti adalah konsep yang lebih abstrak. Variabel instan secara harfiah hanya slot penyimpanan, seperti slot di struct. Biasanya benda-benda lain tidak pernah seharusnya mengaksesnya secara langsung. Properti, di sisi lain, adalah atribut dari objek Anda yang dapat diakses (kedengarannya samar dan itu seharusnya). Biasanya properti akan mengembalikan atau menetapkan variabel instan, tetapi bisa menggunakan data dari beberapa atau tidak sama sekali. Sebagai contoh:

@interface Person : NSObject {
    NSString *name;
}

    @property(copy) NSString *name;
    @property(copy) NSString *firstName;
    @property(copy) NSString *lastName;
@end

@implementation Person
    @synthesize name;

    - (NSString *)firstName {
        [[name componentsSeparatedByString:@" "] objectAtIndex:0];
    }
    - (NSString *)lastName {
        [[name componentsSeparatedByString:@" "] lastObject];
    }
    - (NSString *)setFirstName:(NSString *)newName {
        NSArray *nameArray = [name componentsSeparatedByString:@" "];
        NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
        self.name = [newNameArray componentsJoinedByString:@" "];
    }
    - (NSString *)setLastName:(NSString *)newName {
        NSArray *nameArray = [name componentsSeparatedByString:@" "];
        NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
        self.name = [newNameArray componentsJoinedByString:@" "];
    }
@end

(Catatan: Kode di atas adalah buggy yang mengasumsikan nama sudah ada dan memiliki setidaknya dua komponen (misalnya "Bill Gates" dan bukan hanya "Gates"). Saya merasa bahwa memperbaiki asumsi tersebut akan membuat titik aktual dari kode kurang jelas, jadi saya hanya menunjukkannya di sini sehingga tidak ada orang yang dengan polos mengulangi kesalahan itu.)


81
2018-05-09 17:29



Properti adalah cara yang ramah untuk menerapkan pengambil / penyetel untuk beberapa nilai, dengan fitur dan sintaks yang berguna tambahan. Properti dapat didukung oleh variabel instan, tetapi Anda juga dapat menentukan pengambil / penyetel untuk melakukan sesuatu yang sedikit lebih dinamis, mis. Anda mungkin mendefinisikan properti lowerCase pada string yang secara dinamis membuat hasil daripada mengembalikan nilai dari beberapa variabel anggota.

Inilah contohnya:

// === In your .h ===

@interface MyObject {
    NSString *propertyName;

}

// ...

@property (nonatomic, retain) NSString *propertyName;

// === In your .m @implementation ===

@synthesize propertyName /* = otherVarName */;

Itu @property garis mendefinisikan properti yang disebut propertyName tipe NSString *. Ini bisa didapatkan / disetel menggunakan sintaks berikut:

myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);

Saat Anda menetapkan atau membaca dari myObject.propertyName Anda benar-benar memanggil metode penyetel / pengambil pada objek.

Itu @synthesize baris memberitahu compiler untuk menghasilkan pengambil / penyetel ini untuk Anda, menggunakan variabel anggota dengan nama properti yang sama untuk menyimpan nilai (atau otherVarName jika Anda menggunakan sintaks dalam komentar).

Bersama @synthesize Anda masih dapat mengganti salah satu pengambil / penyetel dengan menentukan sendiri. Konvensi penamaan untuk metode ini adalah setPropertyName: untuk setter dan propertyName (atau getPropertyName, bukan standar) untuk pengambil. Yang lainnya masih akan dibuat untuk Anda.

Di dalam Anda @property baris Anda dapat menentukan sejumlah atribut di parens untuk properti yang dapat mengotomatisasi hal-hal seperti keamanan dan manajemen memori thread. Secara default properti adalah atom yang berarti kompilator akan membungkus @synthesized mendapatkan / mengatur panggilan dengan kunci yang tepat untuk mencegah masalah konkurensi. Anda dapat menentukan nonatomic Atribut untuk menonaktifkan ini (misalnya pada iPhone Anda ingin menjadikan kebanyakan properti sebagai default nonatomic).

Ada 3 nilai atribut yang mengontrol manajemen memori untuk apa pun @synthesized setter. Yang pertama adalah retain yang akan secara otomatis mengirim release ke nilai-nilai lama dari properti, dan retain ke nilai-nilai baru. Ini sangat berguna.

Yang kedua adalah copy yang akan membuat salinan dari setiap nilai yang dilewatkan dan bukannya mempertahankannya. Ini adalah praktik yang baik untuk digunakan copyuntuk NSString karena seorang penelepon dapat lewat dalam NSMutableString dan mengubahnya dari bawah Anda. copy akan membuat salinan baru dari input yang hanya dapat diakses oleh Anda.

Yang ketiga adalah assign yang melakukan penunjuk lurus tanpa memanggil mempertahankan / merilis pada objek lama atau baru.

Terakhir, Anda juga dapat menggunakan readonly atribut untuk menonaktifkan setter untuk properti.


30
2018-05-09 17:53



Saya menggunakan properti untuk bagian antarmuka - di mana objek berinteraksi dengan objek lain dan variabel instan adalah hal-hal yang Anda butuhkan di dalam kelas Anda - tidak seorang pun tetapi Anda seharusnya melihat dan memanipulasi mereka.


6
2018-06-15 13:54



Secara default, properti readwrite akan didukung oleh variabel instan, yang akan kembali disintesis secara otomatis oleh kompilator.

Variabel instan adalah variabel yang ada dan menyimpan nilainya untuk kehidupan objek. Memori yang digunakan misalnya variabel dialokasikan ketika objek pertama kali dibuat (melalui alokasi), dan dibebaskan ketika objek tersebut tidak dialokasikan.

Kecuali Anda menentukan lain, variabel instan yang disintesis memiliki nama yang sama dengan properti, tetapi dengan awalan garis bawah. Untuk properti yang disebut firstName, misalnya, variabel instans yang disintesis akan disebut _firstName.


3
2018-05-28 11:13



Sebelumnya orang menggunakan properti secara publik dan ivars untuk penggunaan pribadi, tetapi sejak beberapa tahun yang lalu, Anda juga dapat menentukan properti di @implementation untuk menggunakannya secara pribadi. Tapi saya masih menggunakan ivars jika memungkinkan, karena ada lebih sedikit huruf untuk diketik, dan berjalan lebih cepat artikel ini. Itu masuk akal karena properti berarti "berat": mereka seharusnya diakses baik dari getter / setter yang dihasilkan atau yang ditulis secara manual.

Namun, dalam kode terbaru dari Apple, ivars tidak digunakan lagi. Saya kira karena itu lebih seperti objc daripada C/C++, plus lebih mudah untuk menggunakan properti dengan assign, nullable, dll.


1
2018-06-07 13:15