Singleton property access in objective C - objective-c

I'm using a standard, modern singleton class with a singleton holding a CTFontRef, like so:
#interface MySingleton : NSObject {
CTFontRef paintingFont;
}
#property (readonly) CTFontRef paintingFont;
#end
#implementation MySingleton
+ (MySingleton*)sharedInstance
{
static dispatch_once_t once;
static MySingleton *sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
//NB
sharedInstance->paintingFont =
CTFontCreateWithName(CFSTR("Helvetica"), 80.0, nil);
});
return sharedInstance;
}
#end
Then elsewhere I call [[MySingleton sharedinstance] paintingFont].
However, this call returns nil until I insert an underscore before paintingFont like so:
sharedInstance->_paintingFont =
CTFontCreateWithName(CFSTR("Helvetica"), 80.0, nil);
Why is this? Shouldn't the compiler require me to include the underscore? If not what is the purpose of the earlier version? And where did this underscore come in? I never declared the property with an underscore to begin with, I just see these seemingly random insertions of them into variable names in the debugger window.

Since Xcode 4.4, when you declare a #property, the compiler will automatically create an ivar for you and #synthesize the accessor methods. The default ivar is one with an underscore.
Using the -> syntax you access ivars directly and not the property. So, in your sharedInstance method you set your own ivar (without the underscore). However when you later try to access it, you use the [ ] which will use the automatically synthesized getter method to access your property (and the automatically generated ivar with an underscore).
You should use the . notation instead of the -> to access the property. Or simply use the automatically generated ivar called _paintingFont.
You can also make a property readwrite in your implementation file by adding the code below. This will allow you to use the dot syntax in your implementation to set the property, but still leave it readonly for other classes.
#interface MySingleton ()
#property (readwrite) CTFontRef paintingFont;
#end
If you want a different ivar, you can use #synthesize to override it. In both cases, you don't have to declare an ivar anymore.
#implementation MySingleton
#synthesize paintingFont;
....
#end

This is because in declaring a property paintingFont the Obj C compiler creates an instance variable _paintingFont.
In general the setting of a property/variable can either be done by
The instance as in your solution sharedInstance->_paintingFont = ...
Using the property and . notation sharedInstance.paintingFont = .... This calls the generated method setPaintingFont which then assigns to the instance variable.
However in this case the property is readonly so method 2 cannot be used.

Related

Objective-C: Overriding Getter & Setter with Instance Variable (using _) [duplicate]

This question already has answers here:
Error accessing generated ivars when I override setters and getters in Modern Objective-C
(3 answers)
Closed 5 years ago.
I'm learning the Swift programing language and during this I sometimes get in touch with the old Objective-C programming language and its code.
I'm an absolutely beginner and therefore I have some question for better understanding the Setter and Getter.
So, I know that I can create an instance variable through curly braces in the .h file but normally I use properties. These properties are backed by an instance variable and offer automatically a Getter and Setter Method.
Example:
Vehicle .h file:
#interface Vehicle : NSObject
#property int myProperty;
#end
Because I created this property I don't have to declare a Getter and Setter method in the vehicle.m file because they are automatically created by the compiler. So I can create a vehicle-object, set and get the value.
Example
main.m
Vehicle *myvehicle = [[vehicle alloc] init];
[myvehicle myProperty] // myvehicle.myProperty
[myvehicle setMyProperty : 10] // myvehicle.myProperty = 10;
Now I read that it is possible to override the automatically created Getter and Setter method of my created property "myProperty". When declaring my own version of the Getter and Setter I have to declare two methods in the vehicle.h and vehicle.m file. In the vehicle.m file I don't call the object by using the self keyword but by using it's automatically created instance variable (_myProperty). Is it right?
I tried it but alway get an error and I don't know why and what is the point.
Example
Vehicle .h file:
#interface Vehicle : NSObject
#property int myProperty;
-(int) myProperty; //my new Getter method
-(void) setMyProperty: (int)updatedMyProperty; //My new Setter method
#end
vehicle .m file:
#implementation Vehicle
-(int) myProperty {
if (! _myProperty) {
_myProperty = NO;
}
return _myProperty;
}
-(void) setMyProperty: (int)updatedMyProperty {
if (_myProperty == updatedMyProperty) return;
_myProperty = updatedMyProperty;
}
#end
I always get the error "Use of undeclared identifier" and I don't know why. If I understand right I don't have to declare the ivar or its name using #synthesize because the compiler automatically creates the ivar called _myProperty for me. I just have to use #synthesize when I want to change the ivar's name.
I'm not sure why I get stuck and what the point is. Could you explain it?
Thanks in advance!
If you implement all of the accessor methods, the compiler will no longer automatically synthesize the ivar for you. In this case, you have to explicitly do so yourself. E.g.
#synthesize myProperty = _myProperty;
This is only necessary when you have manually implemented all of the accessor methods. The reason is that the compiler is smart enough to know that if you're taking over the accessor methods, you may well not need the ivar, namely that you might be doing something radically different, e.g. computing values from some other property, setting/getting values from some different store, etc. You may want the compiler to synthesize the ivar (in which case you add the above #synthesize statement), but it's equally likely that you've implemented the accessor methods because no backing ivar is needed (in which case you'd omit the above #synthesize statement).
Anyway, staying with your simple example, you get something like:
#interface Vehicle : NSObject
#property (nonatomic) int myProperty; // if you don't write atomic accessor methods, you really should be explicit that this is nonatomic
// as an aside, even if you implement accessor methods, you don't have to declare them here
//
// -(int) myProperty; //my new Getter method
// -(void) setMyProperty: (int)updatedMyProperty; //My new Setter method
#end
And
#implementation Vehicle
// since you implemented all of the accessor properties, you have to manually synthesize the ivar
#synthesize myProperty = _myProperty;
- (int) myProperty {
// do whatever you want here; note, the following doesn't make sense
//
// if (! _myProperty) {
// _myProperty = NO;
// }
return _myProperty;
}
- (void)setMyProperty:(int)updatedMyProperty {
if (_myProperty == updatedMyProperty) return;
_myProperty = updatedMyProperty;
}
#end
Clearly, there's no point in writing these particular accessor methods in the above example, because you're not offering any new functionality, so you wouldn't. You'd just avail yourself of the auto-synthesized accessor methods.
But in those cases that you really need to write your own accessor methods, then you have to explicitly tell the compiler whether you need it to synthesize the ivar for you, too, or not.

Is it ok to have overriden getters of an Objective-C class be static?

I have some existing code I'm modifying from another developer. They have a static NSString declared as follows...
static NSString *myStaticString;
This string should be initialized before use. What I'm looking to do is have a property method overriden which will ensure the variable is set. Here's what my suggested layout would look like...
static NSString *myStaticString;
#interface MyClass ()
#property (readonly) NSString *myProperty;
#end
#implementation MyClass
+(NSString *)myProperty
{
if (!myStaticString)
myStaticString = [#"My string value!" retain];
return myStaticString;
}
#end
The new thing for me here is I've never declared a getter as a static method and to be honest I don't know if that is a good idea or not.
In answer to the question (and I paraphrase) "is it ok to have getters return a pointer to a static?" the answer is yes, it is.
The issue here is, though, that getters are instance methods, and you've defined a class method. So you'll end up with a confusing combination of your explicitly defined class method that happens to bear the same name of an automatically synthesized getter instance method (and, worse, that synthesized getter instance method will just be returning a pointer to some automatically synthesized ivar, which is obviously not what you intended). Bottom line, you are not overriding the getter like you obviously thought you were.
As bbum pointed out, you can easily remedy this by defining this explicitly declared method as an instance method. By doing that, you will thereby be overriding the getter, accomplishing what you probably intended.
Personally, since there's nothing here that requires an instance method, I might be inclined to just retire the property altogether and have the class method return a pointer to the string referenced by your static variable. In that case, I'd suggest one of two approaches:
If the string is truly a constant, then I might do something like:
// MyClass.h
#interface MyClass : NSObject
+ (NSString *)someString;
#end
and
// MyClass.m
#import "MyClass.h"
static NSString * const kSomeInternalConstant = #"my string";
#implementation MyClass
+ (NSString *)someString
{
return kSomeInternalConstant;
}
#end
If the string is defined at runtime, but does not change while the app is running, then I'd replace the MyClass.m with:
// MyClass.m
#import "MyClass.h"
#implementation MyClass
+ (NSString *)someString
{
static NSString *someInternalString = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
someInternalString = ... // set it to be whatever you want
});
return someInternalString;
}
#end
Clearly, replace these variable names with something more logical, but hopefully this illustrates the idea.
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 still can use class methods that access static variables which have only a slightly different syntax.
Here's thread safe example:
// 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;
}
You need it to be an instance method:
-(NSString *)myProperty
{
if (!myStaticString)
myStaticString = [#"My string value!" retain];
return myStaticString;
}
And, yes, that is fine.
• The retain is odd; don't need it, doesn't hurt. Best turn on ARC and be done with it.
• I'd move the static into the method or, if it never changes, just return #"My string value!" directly.
• This is not an uncommon pattern; this class may return a default, static, value and subclasses might override to return a different value, as necessary.
• When initializing a static, use dispatch_once. In this case, it doesn't matter as it is an assignment of a static constant string. But, like the retain, best to follow convention (i.e. eliminate the retain, use dispatch_once or just return the value directly).

Which one is initialized, property or its instance variable

Suppose I have a property called myPropertyName defined in my class MyClassName. Manual memory management is used throughout this post.
MyClassName.h
#import <UIKit/UIKit.h>
#interface MyClassName : NSObject {
#private
NSObject* myPropertyName;
#public
}
#property (nonatomic, retain) NSObject* myPropertyName;
// Some methods prototypes are here
#end
MyClassName.m
#import "MyClassName.h"
#implementation MyClassName
#synthesize myPropertyName;
// Some methods are here
#end
I'm confused with usages such as the place of myPropertyName declaration, its difference between instance variable. For example, what is the difference among these three statement of initialization code, for example, in the customized -(void)init method for my class myClassName.
self.myPropertyName = [[[NSObject alloc] init] autorelease];
This one is calling myPropertyName setter, but I'm not sure what is the name of the instance variable being used in the setter, myPropertyName (since I've declared a #private field named myPropertyName) or _myPropertyName (people say that this one with underbar is the default)?
myPropertyName = [[NSObject alloc] init];
Does this initialize the instance variable of the myPropertyName property? If I don't have #synthesize myPropertyName = _myPropertyName;, would it be wrong since the default instance variable for the property is said to be _myPropertyName.
_myPropertyName = [[NSObject alloc] init];
Is _myPropertyName still declared as the instance variable for my property myPropertyName even if I use #synthesize myPropertyName; and #private NSObject* myPropertyName;?
In my understanding, a property is just a name (such as myPropertyName), there should be some instance variable encapsulated to be used in actual operations in the code, such as assigning values.
First off, I highly recommend reading Apple's documentation on properties, also linked by nhgrif. However, I understand docs can be a bit dense reading material (though Apple's, I find, are not so bad), so I'll give a brief overview of properties here.
I like examples, so I'm going to rewrite your two classes in a bit more current form.
MyClassName.h
#import <UIKit/UIKit.h>
#interface MyClassName : NSObject
#property (nonatomic, strong) NSObject *myPropertyName;
// method prototypes here
#end
MyClassName.m
#import "MyClassName.h"
#implementation MyClassName
// some methods here
#end
The class MyClassName now has a property called myPropertyName of type NSObject *. The compiler will do a lot of work for you for "free" in this instance. Specifically, it will generate a backing variable, and also generate a setter and getter for myPropertyName. If I were to rewrite the two files, and pretend I'm the compiler, including that stuff, they would look like this:
MyClassName.h
#import <UIKit/UIKit.h>
#interface MyClassName : NSObject {
NSObject *_myPropertyName;
}
#property (nonatomic, strong) NSObject *myPropertyName;
- (void)setMyPropertyName:(NSObject *)obj;
- (NSObject *)myPropertyName;
#end
MyClassName.m
#import "MyClassName.h"
#implementation MyClassName
- (void)setMyPropertyName:(NSObject *)obj
{
_myPropertyName = obj;
}
- (NSObject *)myPropertyName
{
return _myPropertyName;
}
#end
Again, all of this is happening for "free": I'm just showing you what's happening under the hood. Now for your numbered questions.
self.myPropertyName = [[[NSObject alloc] init] autorelease];
First of all, you should probably be using Automatic Reference Counting, or ARC. If you are, you won't be allowed to call autorelease. Ignoring that part, this works fine. Excluding the autorelease, this is exactly equivalent to:
[self setMyPropertyName:[[NSObject alloc] init]];
Which, if you look at the second .m file I wrote out, above, will basically translate to:
`_myPropertyName = [[NSObject alloc] init];
myPropertyName = [[NSObject alloc] init];
As written, this code will give a compiler error, since there is no variable called myPropertyName in this class. If you really want to access the instance variable underlying (or, "backing") the myPropertyName property, you can, by using its real name:
_myPropertyName = [[NSObject alloc] init]; // note the underscore
But most of the time, it's better to use the setter, as in point 1., since that allows for side effects, and for Key-Value Coding, and other good stuff.
_myPropertyName = [[NSObject alloc] init];
Oh. Well you got it. See point 2.
You mentioned that:
I'm confused with usages such as the place of myPropertyName declaration, its difference between instance variable. For example, what is the difference among these three statement of initialization code, for example, in the customized -(void)init method for my class myClassName.
In case it hasn't been made clear, a property is something of an abstract concept; its data is stored in a normal instance variable, typically assigned by the compiler. Its access should usually be restricted to the setter and getter, with important exceptions. To keep this answer short, I won't go into more detail than that.
One more thing: as nhgrif mentioned, you don't need to use the #synthesize keyword anymore. That is implicitly understood by the compiler now.
If you're not sure about any of this, post a comment or, better yet, read the docs.
Let's take this example:
#property NSString *fullName;
If in the implementation, we override the setters and getters, and in these setters and getters, we don't use an instance variable fullName, it is never created. For example:
- (NSString *)fullName
{
return [NSString stringWithFormat:#"%# %#", self.firstName, self.lastName];
}
- (void)setFullName:(NSString *)fullName
{
//logic to split fullName into two strings
//self.firstName = etc
//self.lastName = etc.
}
In this example, there is no instance variable for fullName created.
This is according to Apple's Official Documentation
If, however, you don't override both the setter and getter, an instance variable is created.
As a sidenote, you can declare a property readonly, and then simply overriding the getter (without using the variable) will prevent an ivar being created. Likewise, you can declare a property writeonly and just override the setter.

Objective-C releasing a property declared in a category?

I have a category on an existing class that adds a property and a few methods to the class.
#interface AClass (ACategory) {
NSString *aProperty;
}
#property (nonatomic, retain) NSString *aProperty;
#end
In the implementation file, I want to release this property when the object is deallocated. However, if I declare dealloc in this class, it will override the dealloc from the original class from what I understand. What then is the proper way to release this aProperty when the object is deallocated?
#implementation AClass (ACategory)
#synthesize aProperty;
- (void)dealloc {
[aProperty release];
// this will skip the original dealloc method from what I understand
[super dealloc];
}
#end
Well, this is a little problematic, since your code is wrong.
You can't declare instance variables in a category; using the latest Objective-C ABI, you can declare new instance variables within a class extension (#interface AClass () {//...), but that is different from a category (#interface AClass (ACategory)).
Even if you could, the syntax for instance variable declaration is that they be enclosed in curly braces after the #interface line.
You can declare a property in a category, but you'll have to define its storage without using a new instance variable (hence, #dynamic instead of #synthesize).
As to your actual question, you can't call the original implementation of an overridden method unless you use method-swizzling (facilitated by runtime functions like method_exchangeImplementations). I recommend against doing this anyway; it's really frightening and dangerous.
Update: Explanation of Instance Variables in Class Extensions
A class extension is like a category, but it is anonymous and must be placed within the .m file associated with the original class. It looks like:
#interface SomeClass () {
// any extra instance variables you wish to add
}
#property (nonatomic, copy) NSString *aProperty;
#end
Its implementation must be in the main #implementation block for your class. Thus:
#implementation SomeClass
// synthesize any properties from the original interface
#synthesize aProperty;
// this will synthesize an instance variable and accessors for aProperty,
// which was declared in the class extension.
- (void)dealloc {
[aProperty release];
// perform other memory management
[super dealloc];
}
#end
So, a class extension is useful for keeping private instance variables and methods out of the public interface, but will not help you add instance variables to a class over which you haven't control. There is no issue with overriding -dealloc, because you just implement it like you normally would, whilst including any necessary memory management for the instance variables you introduced within the class extension.
Please note that this stuff works only with the latest 64-bit Objective-C ABI.
As an aside, you can use associated references to "simulate the addition of object instance variables to an existing class".
Essentially, you can add an associated object as below:
static void* ASI_HTTP_REQUEST; // declare inside the category #implementation but outside any method
// And within a method, init perhaps
objc_setAssociatedObject(self,
&ASI_HTTP_REQUEST,
request,
OBJC_ASSOCIATION_RETAIN);
And release the associated object by sending 'nil':
// And release the associated object
objc_setAssociatedObject(self,
&ASI_HTTP_REQUEST,
nil,
OBJC_ASSOCIATION_RETAIN);
The Apple documentation is here.
It took me a while to find, so I hope that it helps someone.

Is there a difference between an "instance variable" and a "property" in Objective-c?

Is there a difference between an "instance variable" and a "property" in Objective-c?
I'm not very sure about this. I think that an "property" is an instance variable that has accessor methods, but I might think wrong.
A property is a more abstract concept. An instance variable is literally just a storage slot, like a slot in a struct. Normally other objects are never supposed to access them directly. A property, on the other hand, is an attribute of your object that can be accessed (it sounds vague and it's supposed to). Usually a property will return or set an instance variable, but it could use data from several or none at all. For example:
#interface Person : NSObject {
NSString *name;
}
#property(copy) NSString *name;
#property(copy) NSString *firstName;
#property(copy) NSString *lastName;
#end
#implementation Person
#synthesize name;
- (NSString *)firstName {
[[name componentsSeparatedByString:#" "] objectAtIndex:0];
}
- (NSString *)lastName {
[[name componentsSeparatedByString:#" "] lastObject];
}
- (NSString *)setFirstName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:#" "];
NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
self.name = [newNameArray componentsJoinedByString:#" "];
}
- (NSString *)setLastName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:#" "];
NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
self.name = [newNameArray componentsJoinedByString:#" "];
}
#end
(Note: The above code is buggy in that it assumes the name already exists and has at least two components (e.g. "Bill Gates" rather than just "Gates"). I felt that fixing those assumptions would make the actual point of the code less clear, so I'm just pointing it out here so nobody innocently repeats those mistakes.)
A property is a friendly way of implementing a getter/setter for some value, with additional useful features and syntax. A property can be backed by an instance variable, but you can also define the getter/setter to do something a bit more dynamic, e.g. you might define a lowerCase property on a string which dynamically creates the result rather than returning the value of some member variable.
Here's an example:
// === In your .h ===
#interface MyObject {
NSString *propertyName;
}
// ...
#property (nonatomic, retain) NSString *propertyName;
// === In your .m #implementation ===
#synthesize propertyName /* = otherVarName */;
The #property line defines a property called propertyName of type NSString *. This can be get/set using the following syntax:
myObject.propertyName = #"Hello World!";
NSLog("Value: %#", myObject.propertyName);
When you assign to or read from myObject.propertyName you are really calling setter/getter methods on the object.
The #synthesize line tells the compiler to generate these getter/setters for you, using the member variable with the same name of the property to store the value (or otherVarName if you use the syntax in comments).
Along with #synthesize you can still override one of the getter/setters by defining your own. The naming convention for these methods is setPropertyName: for the setter and propertyName (or getPropertyName, not standard) for the getter. The other will still be generated for you.
In your #property line you can define a number of attributes in parens for the property that can automate things like thread-safety and memory management. By default a property is atomic meaning the compiler will wrap #synthesized get/set calls with appropriate locks to prevent concurrency issues. You can specify the nonatomic attribute to disable this (for example on the iPhone you want to default most properties to nonatomic).
There are 3 attribute values that control memory management for any #synthesized setters. The first is retain which will automatically send release to old values of the property, and retain to the new values. This is very useful.
The second is copy which will make a copy of any values passed in rather than retaining them. It is good practice to use copy for NSString because a caller could pass in an NSMutableString and change it out from under you. copy will make a new copy of the input which only you have access to.
The third is assign which does a straight pointer assign without calling retain/release on the old or new object.
Lastly you can also use the readonly attribute to disable the setter for the property.
I use properties for the interface part - where the object interfaces with other objects
and instance variables are stuff that you need inside your class - nobody but you is supposed to see and manipulate those.
By default, a readwrite property will be backed by an instance variable, which will again be synthesized automatically by the compiler.
An instance variable is a variable that exists and holds its value for the life of the object. The memory used for instance variables is allocated when the object is first created (through alloc), and freed when the object is deallocated.
Unless you specify otherwise, the synthesized instance variable has the same name as the property, but with an underscore prefix. For a property called firstName, for example, the synthesized instance variable will be called _firstName.
Previously people use properties publicly and ivars for private usage, but since several years ago, you can also define properties in #implementation to use them privately. But I'd still use ivars when possible, since there are less letters to type, and it runs faster according to this article. It makes sense since properties are mean to be "heavy": they are supposed to be accessed from either generated getters/setters or the ones manually written.
However, in recent codes from Apple, ivars are not used anymore. I guess because it's more like objc rather than C/C++, plus it's easier to use properties with assign, nullable, etc.
Objective-C Property vs Instance variable (iVar)
[Swift variable, property...]
Instance variable
#interface SomeClass: NSObject
NSString *someVariable;
#end
Property
#interface SomeClass: NSObject
#property (nonatomic, strong) NSString *someVariable;
#end
Property uses Instance variable inside. property = variable + bounded getter/setter. It is a method call with variable syntax and access
#property generates getter and setter methods(accessor methods) which uses backing ivar(aka backing field) which you can use via underscore _<var_name> (_someVariable).
Since it calls a method - method dispatch mechanism is used that is why KVO[About] can be applied
When you override accessor methods backing iVar is not generated that is why you can declare a new property explicitly or use #synthesize[About] to generate a new one or link with existing
#import "SomeClass.h"
#interface SomeClass()
#property (nonatomic, strong) NSString *someVariable;
#end
#implementation SomeClass
- (void) foo {
//property getter method
NSString *a1 = self.someVariable; //NSString *a1 = [self someVariable];
//property setter method
self.someVariable = #"set someVariable"; //[self setSomeVariable:#"set someVariable"];
//iVar read
NSString *a2 = _someVariable;
//iVar write
_someVariable = #"set iVar";
}
//if you overriding someVariable getter and setter the iVar(_someVariable) is not generated, that is why you can:
//1. create some variable explicitly
NSString *_someVariable;
//or
//2. use #synthesize
#synthesize someVariable = _someVariable;
//overriding
- (NSString*) someVariable {
return _someVariable;
}
- (void)setSomeVariable: (NSString*) updatedSomeVariable {
_someVariable = updatedSomeVariable;
}
#end
[property attributes]