Objective C _underscore vs self.variable - objective-c

I know this question has been asked before but possibly not in the same context. My question is that I have a singleton class that is only dipatched_once in the lifetime of the app. In the class I have some methods that are accessing the instance variables and acting upon if they have been set on the instance. This is example of how I am attempting to access them:
// .m file:
Interface:
#property (nonatomic, assign, readwrite) BOOL userLoggedIn;
Implementation:
// method:
-(void)someMethod{
if(!_userLoggedIn){
}
else {
}
}
I know I can also use self to evaluate the value like this:
-(void)someMethod{
if(self.userLoggedIn){
}
else {
}
}
Wondering which is correct way of accessing the value? I am not synthesizing the properties since they are all declared in the interface only in the .m file. Thanks for the help!

It depends.
Do you want the accessor invoked or not? _variable is direct access. self.variable invokes -variable, which is automatically synthesized by the compiler.
The former does not trigger KVO when the value changes. The latter does. That may be a feature or anti-feature.
But, whichever you choose, especially for write operations, make it consistent or else you'll be tracking down bugs in the future.
A general rule:
access directly in -init/-dealloc
access through setter/getter (dot syntax) everywhere else
Note also that direct access will not respect atomic.

Related

Define semi public variable in objectiveC

I'd like to define a member in objective C class that can only be read outside the class (public getter). The writing (setter) however shell remain private.
I've read that It's possible to conceal object's setter using the readonly property while exposing the getter using #synthesize syntax but I'm not sure how it works exactly.
Base on this information here's what I did, and I wonder what's happening here under the hood, and if this is the proper way of doing so ?
#interface MyObject : NSObject
//This line suppose to conceal both getter and setter.
#property (readonly) MyCppBaseObject *myCppBaseObject;
- (void)setMyCppBaseObject:(NSString *)SomeInput;
#end
// This line suppose to tell the compiler that the getter is exposed
#synthesize myCppBaseObject = _myCppBaseObject;
#implementation MyObject
-(void)setMyCppBaseObject:(NSString *)SomeInput {
if (someCondition) {
self.myCppBaseObject = new myCppObjectDerive1(...);
} else {
self.myCppBaseObject = new myCppObjectDerive2(...);
}
}
#end
P.S. I've seen a different approach explained in the following link, but I wish to understand the above implementation.
First, you should use the private extension described in the link you provide. That's the correct way to do this.
But to your question, what you've written here is not quite correct.
#property (readonly) MyCppBaseObject *myCppBaseObject;
This line makes a promise to implement -myCppBaseObject. That's all it does. It's just a promise. If you fail to live up to your promise, the compiler will auto-generate (synthesize) one for you using a backing ivar.
- (void)setMyCppBaseObject:(NSString *)SomeInput;
This line is not correct for your purposes. It's making a public setter. But you said you don't want the setter to be public. You could put this in a private extension, however.
#synthesize myCppBaseObject = _myCppBaseObject;
This asks the compiler to create a backing ivar _myCppBaseObject for the property myCppBaseObject. This is the default behavior, however, and so isn't required. (There was a time when it was, but that was a very long time ago.)
-(void)setMyCppBaseObject:(NSString *)SomeInput {
if (someCondition) {
self.myCppBaseObject = new myCppObjectDerive1(...);
} else {
self.myCppBaseObject = new myCppObjectDerive2(...);
}
}
This code is completely incorrect. It is an infinite loop, since self.x =... is syntactic sugar for [self setX:...]. What you mean is:
_myCppBaseObject = ...
You're going to create a lot of headaches having the name of the custom setter be exactly the expected name of the default setter, but with a different type. Don't do this. In theory it could work most of the time, but don't. Especially when there's dot-syntax involved. Especially since one of your objects does not appear to be ARC-compatible (i.e. a C++ object), this is going to really be a trap for really confusing problems. Name your setter differently.

Objective C: I need some advice regarding properties vs ivars

I looked up my current problem on stackoverflow and many other website outlets, but I am a little confused to be quite honest. Should I only use properties when another class needs access to it and ivars when it is being used for only my private class? This is what I am getting so far, although I did hear some other things about when to use ivars and properties. I am just trying to keep my code clean and more modern. Any clarification will be appreciated.
This is a very opinion based topic. So I'm trying to stay with uncontroversial facts and advice:
Never access ivars from outside of the class. Public access would always be done through properties and their accessors or other methods. Nowadays headers should never contain ivar declarations.
Using ivars internally is possible and not uncommon. ARC makes this easy for object types, as ownership is handled automatically.
Using properties gives you proper ownership handling for NSString, NSArray et al. (copy).
Also, in some cases they can help with thread safety (atomic).
Using properties internally could make KVO compliance or other side effects easier to implement.
Using private properties is the standard pattern for exposing IBOutlets.
Properties can be queried during runtime. This is seldom needed, though.
Private properties have the problem of polluting the method namespace for a class. Unintentional overrides can occur.
The actual decision whether or not to use ivars in the implementation is a matter of personal preference. It is affected by many subtle details from code style.
In my opinion - you should only use properties, which are backed by an ivar if you didn't override the getter and the setter.
You should declare them in the public interface to make them public, and declare them in the private interface, that's right, to make them private.
There are many advantages to this, some are:
Perform lazy instantiation in the getter
Do validation in the setter
Make a property readonly public and readwrite privately
Within your class, you should almost always access your properties through the getter/setter unless:
You want to avoid the behavior you implemented in these methods (lazy instantiation, validation)
You are in the initializer
You are in the getter/setter
Here's an example of how of some of the following points:
#interface SomeObject : NSObject
#property (strong, nonatomic) NSMutableArray * objects;
#property (readonly, nonatomic, getter=isActive) BOOL active; // Public read-only
#end
#interface SomeObject()
#property (readwrite, nonatomic, getter=isActive) BOOL active; // Can be updated internally
#property (nonatomic, getter=isVisible) BOOL visible;
#end
#implementation SomeObject
- (NSMutableArray)objects {
if (!_objects) {
_objects = [NSMutableArray array]; // Lazy instantiate when first accessed
}
return _objects;
}
- (BOOL)isActive {
return _isActive && self.isVisible; // Cannot be active if not visible
}
- (BOOL)setActive:(BOOL)active {
self.visible = active; // Keep visibility same as active
_active = active;
}
-(BOO)setVisible:(BOOL)visible {
_visible = visible;
// perform animation or something else...
}
#end
Any of this cannot be achieved using ivars.
You should use declared properties inside and outside your class. Most developers say that you should only set the ivar behind a property in initializers. (I do not agree and use setters and getters in this case, too, but I'm in minority.)

Proper way to perform additional code when setting properties

This might seem like a basic question but I'm still getting a handle on properties so please bear with me.
I have a custom NSView subclass that does its own drawing. I've set up support for different styles with a #property for setters and a typedef enum for human-readable integers. It works great, but the view won't redraw after setting its style unless I manually call setNeedsDisplay:YES on the control or resize its parent window.
Logically one would think the solution would be to simply do a [self setNeedsDisplay:YES] in the classes' setStyle: method, but I cannot for the life of me figure out how to properly do it. Whenever I try to override setStyle: it just complains, "Writable atomic property 'style' cannot pair a synthesized getter with a user defined setter".
What should be done in this situation?
Ideally, you would just declare your actual ivar/storage as a private property, then manually implement the setter setStyle:. In the implementation of setStyle:, set your private property/state, and perform your updates. So you just abstract the data from the client's interface. There are other ways to approach this, such as directly setting the ivar.
So an implementation may take the form:
MONThing.h
#interface MONThing : NSObject
- (void)setStyle:(t_style)pStyle; // << the client's interface
#end
MONThing.m
#interface MONThing ()
#property (nonatomic, assign, readwrite) t_style userStyle; // << the actual storage
#end
#implementation MONThing
- (void)setStyle:(t_style)pStyle
{
// validate parameter
// set our data
self.userStyle = pStyle;
// perform effects
[self setNeedsDisplay:true];
}
Over time, you will learn multiple ways to accomplish this, and when you would favor one over the other.
If you a setting your own setter then do not use #synthesize and #property. These are for automatic creation of the setter and getter methods. Declaring the variable in the interface file is enough.
Take a look at this question. To copy over the answer from the other question:
If you declare a #property to be atomic then do one of the following:
use #dynamic or;
use #synthesize and keep the synthesized setter and getter or;
provide a manual implementation of both the setter and the getter (without using one of the above directives).

Is it possible to extend an existing Objective-C Block?

I have a class using a Block defined in the header like this:
#property (readwrite, copy) RequestSucceededBlock succeededBlock;
The property succeededBlock is already set with a Block. Is there a way to override this Block with another that still calls the original, similar to class inheritance?
I assume this is not possible, because class inheritance should be used to express things like that. Is it still possible?
Assuming you're talking about trying to have a replacement block in a subclass that still calls the superclass block, you can't inject a block into an existing block but you can fake it as follows:
// in MySubclass.h
#property (nonatomic, copy) RequestSucceededBlock subclassSucceededBlock;
// in MySubclass.m
- (RequestSucceededBlock)succeededBlock
{
[return subclassSucceededBlock];
}
- (void)setSucceededBlock:(RequestSucceededBlock)newSucceededBlock
{
// make sure this conforms to the definition of RequestSucceededBlock
RequestSucceededBlock combinedBlock = ^{
dispatch_async(dispatch_get_current_queue(), newSucceededBlock);
dispatch_async(dispatch_get_current_queue(), [super succeededBlock]);
};
subclassSucceededBlock = combinedBlock;
}
This is a bit odd though b/c it assumes the superclass has a default block assigned to succeededBlock that you want to dispatch. If your question has a different use in mind please clarify and I'll see if I can update this.
EDIT: added copy to iVar

Objective C small syntax clarification

I have seen this code in most of the time. Here there are two variable names defined and in the implementation it synthesizing by assigning. Whats the purpose of doing some thing like this? Like keeping 2 separate variable names. Is this sort of a convention?
Test.h
#interface Test {
id<something> _variable1;
}
#property (nonatomic, retain) id<something> variable2;
Test.m
#synthesize variable2 = _variable1
There is only one variable. The thing named variable2 is actually a property, which is basically a syntactic shortcut for a get/set method pair. When defining a property, you can either write the get/set methods explicitly...
- (void)setVariable2:(id<something>)value {
if (_variable1 != value) {
[_variable1 release];
_variable1 = [value retain];
}
}
- (id<something>)variable2 {
return _variable1;
}
...or use the #synthesize construct to generate the above methods automatically, thus sparing you a lot of monotonous typing. (It also emits code to release _variable1 on destruction of the object, which I haven't included here.)
Sometimes, however, you might want to implement one or other of these methods differently to the default. In this case, you would write your own. You can even mix together #synthesize and a custom version of just one of the methods.