Jawaban:
properti memiliki arti tertentu dalam Objective-C, tapi saya pikir Anda berarti sesuatu yang setara dengan variabel statis? Misalnya hanya satu contoh untuk semua jenis Foo?
Untuk mendeklarasikan fungsi kelas di Objective-C Anda menggunakan awalan + alih-alih - sehingga implementasi Anda akan terlihat seperti:
// Foo.h
@interface Foo {
}
+ (NSDictionary *)dictionary;
// Foo.m
+ (NSDictionary *)dictionary {
static NSDictionary *fooDict = nil;
if (fooDict == nil) {
// create dict
}
return fooDict;
}
.
sintaks -accessor tidak terikat properti di Objective-C, itu hanya disusun-in pintas untuk metode apapun yang kembali sesuatu tanpa mengambil args apapun. Dalam hal ini saya lebih suka - saya pribadi lebih suka .
sintaksis untuk setiap penggunaan di mana kode klien bermaksud untuk mendapatkan sesuatu, tidak melakukan tindakan (bahkan jika kode implementasi dapat membuat sesuatu sekali, atau melakukan tindakan efek samping) . .
Sintaks penggunaan yang berat juga menghasilkan kode yang lebih mudah dibaca: keberadaan […]
s berarti sesuatu yang signifikan sedang dilakukan ketika mengambil .
alih menggunakan sintaks.
Saya menggunakan solusi ini:
@interface Model
+ (int) value;
+ (void) setValue:(int)val;
@end
@implementation Model
static int value;
+ (int) value
{ @synchronized(self) { return value; } }
+ (void) setValue:(int)val
{ @synchronized(self) { value = val; } }
@end
Dan saya menemukannya sangat berguna sebagai pengganti pola Singleton.
Untuk menggunakannya, cukup akses data Anda dengan notasi titik:
Model.value = 1;
NSLog(@"%d = value", Model.value);
self
artinya di dalam metode kelas?
self
adalah objek yang menerima pesan . Dan karena kelas juga objek , dalam hal ini self
berartiModel
@synchronized
?
Seperti yang terlihat di WWDC 2016 / XCode 8 ( apa yang baru dalam sesi LLVM @ 5: 05). Properti kelas dapat dideklarasikan sebagai berikut
@interface MyType : NSObject
@property (class) NSString *someString;
@end
NSLog(@"format string %@", MyType.someString);
Perhatikan bahwa properti kelas tidak pernah disintesis
@implementation
static NSString * _someString;
+ (NSString *)someString { return _someString; }
+ (void)setSomeString:(NSString *)newString { _someString = newString; }
@end
static
variabel ( ) masih harus dideklarasikan dan digunakan, dan metode diimplementasikan secara eksplisit, seperti sebelumnya. Sintaks dot sudah bekerja sebelumnya juga. Secara keseluruhan, ini terdengar seperti kesepakatan yang lebih besar dari yang sebenarnya.
Jika Anda mencari yang setara dengan tingkat kelas @property
, maka jawabannya adalah "tidak ada yang seperti itu". Tapi ingat, @property
itu hanya gula sintaksis; itu hanya menciptakan metode objek bernama tepat.
Anda ingin membuat metode kelas yang mengakses variabel statis yang, seperti orang lain katakan, hanya memiliki sintaks yang sedikit berbeda.
UIDevice.currentDevice.identifierForVendor
bekerja untukku.
Inilah cara aman untuk melakukannya:
// Foo.h
@interface Foo {
}
+(NSDictionary*) dictionary;
// Foo.m
+(NSDictionary*) dictionary
{
static NSDictionary* fooDict = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
// create dict
});
return fooDict;
}
Pengeditan ini memastikan bahwa fooDict hanya dibuat sekali.
Dari dokumentasi Apple : "dispatch_once - Menjalankan objek blok sekali dan hanya sekali seumur hidup aplikasi."
Initializer element is not a compile-time constant
.
Pada Xcode 8 Objective-C sekarang mendukung properti kelas:
@interface MyClass : NSObject
@property (class, nonatomic, assign, readonly) NSUUID* identifier;
@end
Karena properti kelas tidak pernah disintesis, Anda perlu menulis implementasi Anda sendiri.
@implementation MyClass
static NSUUID*_identifier = nil;
+ (NSUUID *)identifier {
if (_identifier == nil) {
_identifier = [[NSUUID alloc] init];
}
return _identifier;
}
@end
Anda mengakses properti kelas menggunakan sintaks dot normal pada nama kelas:
MyClass.identifier;
Properti hanya memiliki nilai dalam objek, bukan kelas.
Jika Anda perlu menyimpan sesuatu untuk semua objek kelas, Anda harus menggunakan variabel global. Anda dapat menyembunyikannya dengan mendeklarasikannya static
di file implementasi.
Anda juga dapat mempertimbangkan menggunakan hubungan spesifik antara objek Anda: Anda mengaitkan peran master ke objek tertentu dari kelas Anda dan menautkan objek lain ke master ini. Master akan memegang kamus sebagai properti sederhana. Saya berpikir tentang pohon seperti yang digunakan untuk hierarki tampilan dalam aplikasi Kakao.
Pilihan lain adalah membuat objek dari kelas khusus yang terdiri dari kamus 'kelas' Anda dan satu set semua objek yang terkait dengan kamus ini. Ini seperti NSAutoreleasePool
di Cocoa.
Mulai dari Xcode 8, Anda dapat menggunakan atribut properti kelas seperti dijawab oleh Berbie.
Namun, dalam implementasi, Anda perlu mendefinisikan pengambil kelas dan penyetel untuk properti kelas menggunakan variabel statis sebagai pengganti iVar.
Sampel
@interface Sample: NSObject
@property (class, retain) Sample *sharedSample;
@end
Contoh.m
@implementation Sample
static Sample *_sharedSample;
+ ( Sample *)sharedSample {
if (_sharedSample==nil) {
[Sample setSharedSample:_sharedSample];
}
return _sharedSample;
}
+ (void)setSharedSample:(Sample *)sample {
_sharedSample = [[Sample alloc]init];
}
@end
Jika Anda memiliki banyak properti tingkat kelas maka pola singleton mungkin dalam urutan. Sesuatu seperti ini:
// Foo.h
@interface Foo
+ (Foo *)singleton;
@property 1 ...
@property 2 ...
@property 3 ...
@end
Dan
// Foo.m
#import "Foo.h"
@implementation Foo
static Foo *_singleton = nil;
+ (Foo *)singleton {
if (_singleton == nil) _singleton = [[Foo alloc] init];
return _singleton;
}
@synthesize property1;
@synthesize property2;
@synthesise property3;
@end
Sekarang akses properti tingkat kelas Anda seperti ini:
[Foo singleton].property1 = value;
value = [Foo singleton].property2;
dispatch_once
sini.
[Coba solusi ini sederhana] Anda dapat membuat variabel statis di kelas Swift kemudian memanggilnya dari kelas Objective-C.