Karena saya tidak dapat membuat properti yang disintesis dalam Kategori di Objective-C, saya tidak tahu cara mengoptimalkan kode berikut:
@interface MyClass (Variant)
@property (nonatomic, strong) NSString *test;
@end
@implementation MyClass (Variant)
@dynamic test;
- (NSString *)test {
NSString *res;
//do a lot of stuff
return res;
}
@end
Metode pengujian dipanggil beberapa kali saat runtime dan saya melakukan banyak hal untuk menghitung hasilnya. Biasanya menggunakan properti yang disintesis, saya menyimpan nilai dalam IVar _test saat pertama kali metode dipanggil, dan hanya mengembalikan IVar ini lain kali. Bagaimana saya bisa mengoptimalkan kode di atas?
objective-c
categories
dhrm
sumber
sumber
Jawaban:
Metode @ lorean akan berfungsi (catatan: jawaban sekarang dihapus) , tetapi Anda hanya memiliki satu slot penyimpanan. Jadi, jika Anda ingin menggunakan ini pada beberapa instance dan setiap instance menghitung nilai yang berbeda, itu tidak akan berfungsi.
Untungnya, runtime Objective-C memiliki hal yang disebut Associated Objects yang dapat melakukan apa yang Anda inginkan:
sumber
@selector(test)
sebagai kunci, seperti yang dijelaskan di sini: stackoverflow.com/questions/16020918/….h-file
.m-file
Sama seperti properti biasa - dapat diakses dengan notasi titik
Sintaks yang lebih mudah
Sebagai alternatif, Anda dapat menggunakan
@selector(nameOfGetter)
alih-alih membuat kunci penunjuk statis seperti:Untuk detail lebih lanjut, lihat https://stackoverflow.com/a/16020927/202451
sumber
@dynamic objectTag;
.@dynamic
berarti penyetel & pengambil akan dibuat di tempat lain, tetapi dalam hal ini mereka diterapkan di sini.Jawaban yang diberikan bekerja dengan baik dan proposal saya hanyalah perpanjangan dari itu yang menghindari penulisan terlalu banyak kode boilerplate.
Untuk menghindari penulisan berulang kali metode pengambil dan penyetel untuk properti kategori, jawaban ini memperkenalkan makro. Selain itu, makro ini memudahkan penggunaan properti tipe primitif seperti
int
atauBOOL
.Pendekatan tradisional tanpa makro
Secara tradisional Anda mendefinisikan properti kategori seperti
Kemudian Anda perlu menerapkan metode pengambil dan penyetel menggunakan objek terkait dan pemilih get sebagai kuncinya ( lihat jawaban asli ):
Pendekatan yang saya sarankan
Sekarang, dengan menggunakan makro Anda akan menulis:
Makro ditentukan sebagai berikut:
Makro
CATEGORY_PROPERTY_GET_SET
menambahkan pengambil dan penyetel untuk properti tertentu. Properti read-only atau write-only akan menggunakan makroCATEGORY_PROPERTY_GET
danCATEGORY_PROPERTY_SET
masing-masing.Tipe primitif membutuhkan lebih banyak perhatian
Karena tipe primitif bukan objek, makro di atas berisi contoh untuk digunakan
unsigned int
sebagai tipe properti. Ia melakukannya dengan membungkus nilai integer ke dalam sebuahNSNumber
objek. Jadi penggunaannya analog dengan contoh sebelumnya:Mengikuti pola ini, Anda hanya dapat menambahkan lebih banyak macro untuk juga mendukung
signed int
,BOOL
, dll ...Batasan
Semua makro digunakan
OBJC_ASSOCIATION_RETAIN_NONATOMIC
secara default.IDE seperti Kode Aplikasi saat ini tidak mengenali nama penyetel saat memfaktorkan ulang nama properti. Anda perlu mengganti namanya sendiri.
sumber
#import <objc/runtime.h>
di file .m kategori jika tidak. kesalahan waktu kompilasi: Deklarasi implisit dari fungsi 'objc_getAssociatedObject' tidak valid di C99 muncul. stackoverflow.com/questions/9408934/…Cukup gunakan libextobjc perpustakaan :
file-h:
m-file:
Selengkapnya tentang @synthesizeAssociation
sumber
Hanya diuji dengan iOS 9 Contoh: Menambahkan properti UIView ke UINavigationBar (Category)
UINavigationBar + Helper.h
UINavigationBar + Helper.m
sumber
Solusi lain yang mungkin, mungkin lebih mudah, yang tidak digunakan
Associated Objects
adalah mendeklarasikan variabel dalam file implementasi kategori sebagai berikut:Kelemahan dari implementasi semacam ini adalah bahwa objek tidak berfungsi sebagai variabel instan, melainkan sebagai variabel kelas. Selain itu, atribut properti tidak dapat ditetapkan (seperti yang digunakan di Objek Terkait seperti OBJC_ASSOCIATION_RETAIN_NONATOMIC)
sumber