Reputation: 16196
Maybe this is obvious, but I don't know how to declare class properties in Objective-C.
I need to cache per-class a dictionary and wonder how put it in the class.
Upvotes: 231
Views: 161820
Reputation: 19476
As seen on WWDC 2016/XCode 8 (what's new in LLVM session @5:05). Class properties can be declared as follows
@interface MyType : NSObject
@property (class) NSString *someString;
@end
NSLog(@"format string %@", MyType.someString);
Note that class properties are never synthesized
@implementation
static NSString * _someString;
+ (NSString *)someString { return _someString; }
+ (void)setSomeString:(NSString *)newString { _someString = newString; }
@end
Upvotes: 120
Reputation: 101
Starting from Xcode 8, you can use the class property attribute as answered by Berbie.
However, in the implementation, you need to define both class getter and setter for the class property using a static variable in lieu of an iVar.
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
Upvotes: 9
Reputation: 825
[Try this solution it's simple] You can create a static variable in a Swift class then call it from any Objective-C class.
Upvotes: -4
Reputation: 1028
As of Xcode 8 Objective-C now supports class properties:
@interface MyClass : NSObject
@property (class, nonatomic, assign, readonly) NSUUID* identifier;
@end
Since class properties are never synthesised you need to write your own implementation.
@implementation MyClass
static NSUUID*_identifier = nil;
+ (NSUUID *)identifier {
if (_identifier == nil) {
_identifier = [[NSUUID alloc] init];
}
return _identifier;
}
@end
You access the class properties using normal dot syntax on the class name:
MyClass.identifier;
Upvotes: 18
Reputation: 58804
properties have a specific meaning in Objective-C, but I think you mean something that's equivalent to a static variable? E.g. only one instance for all types of Foo?
To declare class functions in Objective-C you use the + prefix instead of - so your implementation would look something like:
// Foo.h
@interface Foo {
}
+ (NSDictionary *)dictionary;
// Foo.m
+ (NSDictionary *)dictionary {
static NSDictionary *fooDict = nil;
if (fooDict == nil) {
// create dict
}
return fooDict;
}
Upvotes: 205
Reputation: 4021
Here's a thread safe way of doing it:
// 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;
}
These edits ensure that fooDict is only created once.
From Apple documentation: "dispatch_once - Executes a block object once and only once for the lifetime of an application."
Upvotes: 24
Reputation: 1719
If you have many class level properties then a singleton pattern might be in order. Something like this:
// Foo.h
@interface Foo
+ (Foo *)singleton;
@property 1 ...
@property 2 ...
@property 3 ...
@end
And
// 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
Now access your class-level properties like this:
[Foo singleton].property1 = value;
value = [Foo singleton].property2;
Upvotes: 3
Reputation: 1221
I'm using this solution:
@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
And i found it extremely useful as a replacement of Singleton pattern.
To use it, simply access your data with dot notation:
Model.value = 1;
NSLog(@"%d = value", Model.value);
Upvotes: 122
Reputation: 67879
Properties have values only in objects, not classes.
If you need to store something for all objects of a class, you have to use a global variable. You can hide it by declaring it static
in the implementation file.
You may also consider using specific relations between your objects: you attribute a role of master to a specific object of your class and link others objects to this master. The master will hold the dictionary as a simple property. I think of a tree like the one used for the view hierarchy in Cocoa applications.
Another option is to create an object of a dedicated class that is composed of both your 'class' dictionary and a set of all the objects related to this dictionary. This is something like NSAutoreleasePool
in Cocoa.
Upvotes: 7
Reputation: 81122
If you're looking for the class-level equivalent of @property
, then the answer is "there's no such thing". But remember, @property
is only syntactic sugar, anyway; it just creates appropriately-named object methods.
You want to create class methods that access static variables which, as others have said, have only a slightly different syntax.
Upvotes: 63