Saya mencoba mencari tahu sesuatu dengan bahasa Apple Swift yang baru. Katakanlah saya dulu melakukan sesuatu seperti yang berikut di Objective-C. Saya memiliki readonly
properti, dan mereka tidak dapat diubah secara individual. Namun, menggunakan metode tertentu, properti diubah secara logis.
Saya ambil contoh berikut, jam yang sangat sederhana. Saya akan menulis ini di Objective-C.
@interface Clock : NSObject
@property (readonly) NSUInteger hours;
@property (readonly) NSUInteger minutes;
@property (readonly) NSUInteger seconds;
- (void)incrementSeconds;
@end
@implementation Clock
- (void)incrementSeconds {
_seconds++;
if (_seconds == 60) {
_seconds = 0;
_minutes++;
if (_minutes == 60) {
_minutes = 0;
_hours++;
}
}
}
@end
Untuk tujuan tertentu, kami tidak dapat menyentuh detik, menit dan jam secara langsung, dan itu hanya diperbolehkan untuk meningkatkan detik demi detik menggunakan metode. Hanya metode ini yang dapat mengubah nilai dengan menggunakan trik variabel instan.
Karena tidak ada hal seperti itu di Swift, saya mencoba mencari yang setara. Jika saya melakukan ini:
class Clock : NSObject {
var hours: UInt = 0
var minutes: UInt = 0
var seconds: UInt = 0
func incrementSeconds() {
self.seconds++
if self.seconds == 60 {
self.seconds = 0
self.minutes++
if self.minutes == 60 {
self.minutes = 0
self.hours++
}
}
}
}
Itu akan berhasil, tetapi siapa pun dapat mengubah properti secara langsung.
Mungkin saya sudah memiliki desain yang buruk di Objective-C dan itulah mengapa potensi Swift baru yang setara tidak masuk akal. Jika tidak dan jika seseorang memiliki jawaban, saya akan sangat berterima kasih;)
Mungkin Mekanisme Akses Kontrol di masa depan yang dijanjikan oleh Apple adalah jawabannya?
Terima kasih!
sumber
Jawaban:
Cukup awali deklarasi properti dengan
private(set)
, seperti:private
menyimpannya lokal ke file sumber, sementarainternal
menyimpannya lokal ke modul / proyek.private(set)
menciptakanread-only
properti, sementaraprivate
mengatur keduanya,set
danget
ke pribadi.sumber
Ada dua cara dasar untuk melakukan apa yang Anda inginkan. Cara pertama adalah dengan memiliki properti pribadi dan dan properti publik yang dihitung yang mengembalikan properti itu:
Tetapi ini dapat dicapai dengan cara yang berbeda dan lebih pendek, seperti yang dinyatakan dalam bagian "Kontrol Akses" dari buku "The Swift Programming Language" :
Sebagai catatan tambahan, Anda HARUS memberikan inisialisasi publik saat mendeklarasikan tipe publik. Bahkan jika Anda memberikan nilai default untuk semua properti,
init()
harus didefinisikan secara eksplisit untuk publik:Ini juga dijelaskan di bagian buku yang sama, ketika berbicara tentang inisialisasi default.
sumber
Karena tidak ada kontrol akses (artinya Anda tidak dapat membuat kontrak akses yang berbeda tergantung pada siapa peneleponnya), inilah yang akan saya lakukan untuk saat ini:
Ini hanya menambah tingkat tipuan, seolah-olah, untuk mengarahkan akses ke konter; kelas lain dapat membuat Jam dan kemudian mengakses penghitungnya secara langsung. Tetapi idenya - yaitu, kontrak yang kami coba buat - adalah bahwa kelas lain harus menggunakan properti dan metode tingkat atas Clock saja. Kami tidak dapat menegakkan kontrak itu, tetapi sebenarnya sangat tidak mungkin untuk menerapkan di Objective-C juga.
sumber
Sebenarnya kontrol akses (yang belum ada di Swift) tidak ditegakkan seperti yang Anda pikirkan di Objective C. Orang - orang dapat memodifikasi variabel readonly Anda secara langsung, jika mereka benar-benar menginginkannya. Mereka hanya tidak melakukannya dengan antarmuka publik kelas.
Anda dapat melakukan hal serupa di Swift (potong & rekatkan kode Anda, ditambah beberapa modifikasi, saya tidak mengujinya):
yang sama dengan apa yang Anda miliki di Objective C kecuali bahwa properti yang disimpan sebenarnya terlihat di antarmuka publik.
Di swift Anda juga bisa melakukan sesuatu yang lebih menarik, yang juga bisa Anda lakukan di Objective C, tetapi mungkin lebih cantik di swift (diedit di browser, saya tidak mengujinya):
sumber