Yanıtlar:
özellikleri Objective-C belirli bir anlamı var, ama statik bir değişken eşdeğer bir şey mi demek istiyorum? Örneğin tüm Foo türleri için sadece bir örnek?
Objective-C sınıf işlevleri bildirmek için yerine + önekini kullanın - böylece uygulamanız şöyle görünecektir:
// Foo.h
@interface Foo {
}
+ (NSDictionary *)dictionary;
// Foo.m
+ (NSDictionary *)dictionary {
static NSDictionary *fooDict = nil;
if (fooDict == nil) {
// create dict
}
return fooDict;
}
.
-Accessor sözdizimi Objective-C özelliklerine bağlı değildir, bu sadece bir derlenmiş içinde kısayol herhangi yöntem için herhangi args almadan döner bir şey. Bu durumda tercih ederim - Ben şahsen .
müşteri kodunun bir şey almak niyetinde olduğu herhangi bir kullanım için sözdizimini tercih ederim , bir eylem gerçekleştirmeyin (uygulama kodu bir kez bir şeyler yaratabilir veya yan etki eylemleri gerçekleştirse bile) . Ağır kullanım .
sözdizimi de daha okunabilir bir kodla sonuçlanır: […]
s'nin varlığı, getirmeler .
sözdizimi kullandığında önemli bir şeyin yapıldığı anlamına gelir .
Bu çözümü kullanıyorum:
@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
Ve Singleton deseninin yerine son derece yararlı buldum.
Kullanmak için, nokta gösterimi ile verilerinize erişmeniz yeterlidir:
Model.value = 1;
NSLog(@"%d = value", Model.value);
self
, sınıf yöntemi içinde yeryüzünde ne anlama geliyor?
self
olduğu mesajı Alındıktan nesne . Ve sınıflar da nesne olduğundan, bu durumda self
anlamına gelirModel
@synchronized
?
WWDC 2016 / XCode 8'de görüldüğü gibi ( LLVM oturumundaki yenilikler @ 5: 05). Sınıf özellikleri aşağıdaki gibi beyan edilebilir
@interface MyType : NSObject
@property (class) NSString *someString;
@end
NSLog(@"format string %@", MyType.someString);
Sınıf özelliklerinin asla sentezlenmediğini unutmayın
@implementation
static NSString * _someString;
+ (NSString *)someString { return _someString; }
+ (void)setSomeString:(NSString *)newString { _someString = newString; }
@end
static
) değişkeni hala bildirilmeli ve kullanılmalı ve yöntemler daha önce olduğu gibi açıkça uygulanmalıdır. Nokta sözdizimi daha önce de çalıştı. Genel olarak, bu gerçekte olduğundan daha büyük bir anlaşma gibi geliyor.
Eğer sınıf düzeyinde bir eşdeğeri arıyorsanız @property
, cevap "böyle bir şey yoktur". Ama unutmayın @property
, yine de sadece sözdizimsel şekerdir; yalnızca uygun şekilde adlandırılmış nesne yöntemleri oluşturur.
Diğerlerinin söylediği gibi, sadece biraz farklı bir sözdizimine sahip olan statik değişkenlere erişen sınıf yöntemleri oluşturmak istiyorsunuz.
UIDevice.currentDevice.identifierForVendor
benim için çalışıyor.
İşte bunu yapmanın güvenli bir yolu:
// 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;
}
Bu düzenlemeler fooDict öğesinin yalnızca bir kez oluşturulmasını sağlar.
Gönderen Elma belgelerinde : "dispatch_once - Bir blok nesnesi yalnızca bir kez bir uygulamanın ömrü boyunca yürütür."
Initializer element is not a compile-time constant
.
Xcode 8'den itibaren Objective-C artık sınıf özelliklerini destekliyor:
@interface MyClass : NSObject
@property (class, nonatomic, assign, readonly) NSUUID* identifier;
@end
Sınıf özellikleri hiçbir zaman sentezlenmediği için kendi uygulamanızı yazmanız gerekir.
@implementation MyClass
static NSUUID*_identifier = nil;
+ (NSUUID *)identifier {
if (_identifier == nil) {
_identifier = [[NSUUID alloc] init];
}
return _identifier;
}
@end
Sınıf özelliklerine, sınıf adındaki normal nokta sözdizimini kullanarak erişirsiniz:
MyClass.identifier;
Özelliklerin sınıflarda değil, yalnızca nesnelerde değerleri vardır.
Bir sınıfın tüm nesneleri için bir şeyler depolamanız gerekiyorsa, global bir değişken kullanmanız gerekir. static
Uygulama dosyasında bildirerek gizleyebilirsiniz .
Ayrıca, nesneleriniz arasında belirli ilişkiler kullanmayı da düşünebilirsiniz: bir master rolünü sınıfınızın belirli bir nesnesiyle ilişkilendirir ve diğer nesneleri bu master'a bağlarsınız. Master sözlüğü basit bir özellik olarak tutacaktır. Kakao uygulamalarında görünüm hiyerarşisinde kullanılan ağaç gibi düşünüyorum.
Başka bir seçenek, hem 'sınıf' sözlüğünüzden hem de bu sözlüğle ilgili tüm nesnelerden oluşan özel bir sınıf nesnesi oluşturmaktır. Bu Kakao'daki gibi bir şey NSAutoreleasePool
.
Xcode 8'den başlayarak Berbie tarafından yanıtlandığı gibi class özelliği özelliğini kullanabilirsiniz.
Ancak, uygulamada, iVar yerine statik bir değişken kullanarak sınıf özelliği için hem sınıf alıcısını hem de ayarlayıcısını tanımlamanız gerekir.
Sample.h
@interface Sample: NSObject
@property (class, retain) Sample *sharedSample;
@end
Sample.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
Sınıf düzeyinde çok sayıda özelliğiniz varsa, tek bir kalıp düzeni olabilir. Bunun gibi bir şey:
// Foo.h
@interface Foo
+ (Foo *)singleton;
@property 1 ...
@property 2 ...
@property 3 ...
@end
Ve
// 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
Şimdi bunun gibi sınıf düzeyi özelliklerinize erişin:
[Foo singleton].property1 = value;
value = [Foo singleton].property2;
dispatch_once
.
[Bu çözümü basit deneyin] Bir Swift sınıfında statik bir değişken oluşturabilir ve bunu herhangi bir Objective-C sınıfından çağırabilirsiniz.