Accessing instance variables: Xcode warnings


James Walker
 

On Dec 14, 2020, at 4:08 PM, Jens Alfke <jens@mooseyard.com> wrote:



On Dec 11, 2020, at 12:33 PM, Alex Zavatone via groups.io <zav=mac.com@groups.io> wrote:

_mType is the internal class scoped copy of it.

self. is safest. It’s wrapped with the get and set accessors.
It's not that much safer, really. There's no difference in single-threaded code. If the property is being read and written on multiple threads, and you declare the property @atomic, the getter and setter will be thread-safe while the direct read/write can in some cases crash. (But only if it's an object pointer, not a scalar.)

In most cases, inside the class implementation I [used to] just access the ivar directly because it's a lot faster and produces smaller code.

Setting the instance variable directly will not be reported to KVO observers. Sometimes that may be what you want, other times not.


 



On Dec 11, 2020, at 12:33 PM, Alex Zavatone via groups.io <zav@...> wrote:

_mType is the internal class scoped copy of it.

self. is safest.  It’s wrapped with the get and set accessors.

It's not that much safer, really. There's no difference in single-threaded code. If the property is being read and written on multiple threads, and you declare the property @atomic, the getter and setter will be thread-safe while the direct read/write can in some cases crash. (But only if it's an object pointer, not a scalar.)

In most cases, inside the class implementation I [used to] just access the ivar directly because it's a lot faster and produces smaller code.

—Jens


Chris Hanson
 

On Dec 11, 2020, at 11:02 AM, Carl Hoefs <newslists@...> wrote:

I have an ObjC class that has an instance variable "property" declared as such:

@property (nonatomic,retain,nonnull) NSString *mType;

This is not an instance variable, this is a property. In Objective-C, like Smalltalk, an instance variable is usually part of the internal implementation of your class. That's why as of Objective-C 2.0 and the new runtime, they can (and should) be declared in the @implementation instead fo the @interface.

(I'd also not name a property something like "mType," but give it a more semantic name.)

In a instance method of this class, I can refer to mType in various ways, with warnings:

mType "Instance variable 'mType' is being directly accessed"

This will be the name of the instance variable providing storage for the property if your `@implementation` has `@synthesize mType;`.

_mType "Use of undeclared identifier '_mType'; did you mean 'mType'?"

This will be the name of the instance variable providing storage for the property if you either have no `@synthesize` for it, or if you have `@synthesize mType = _mtype;` in your `@implementation`.

self.mType (No warning, but is very slow if used in a loop. Needed for blocks)

This is interacting with the property via its accessors, not accessing its storage.

Q1: "Direct" access to an instance variable bypasses its setter/getter methods, but otherwise what is wrong with it?

It all depends what you want. Often in the implementation of a class you know what the invariants you need to maintain are, so you can interact directly with the backing storage for a property. Note that this doesn't have to be an instance variable, that's just the default behavior.

Q2: Sometimes using the underscore form, _mType, quiets the direct access warning; other times Xcode acts like it doesn't know what I'm referring to. What is the underscore intended for?

See above.

Yes I can turn the Xcode warnings off by deleting -Weverything, but I want to do the right thing...

What's right will depend on both context and an understanding of the distinction between the property (an interface) and its underlying storage (an implementation). You can usually 

  -- Chris



Ben Kennedy
 

On 11 Dec 2020, at 11:02 am, Carl Hoefs <newslists@autonomy.caltech.edu> wrote:

Q1: "Direct" access to an instance variable bypasses its setter/getter methods, but otherwise what is wrong with it?
I haven't seen this warning myself (at least recently), but presumably it is intended to draw attention to the fact that you might be unintentionally avoiding the property accessors.

Q2: Sometimes using the underscore form, _mType, quiets the direct access warning; other times Xcode acts like it doesn't know what I'm referring to. What is the underscore intended for?
Do you have a `@synthesize` directive in the implementation? I believe that by default, `@synthesize` with no arguments will create backing store with the same name as the property. Typically, when the backing store is automatically created, it gets named with the underscore prefix. (You can achieve the same thing manually with `@synthesize mType=_mType;`.)

b


Alex Zavatone
 

_mType is the internal class scoped copy of it.

self. is safest. It’s wrapped with the get and set accessors.

On Dec 11, 2020, at 1:02 PM, Carl Hoefs <newslists@autonomy.caltech.edu> wrote:

I have an ObjC class that has an instance variable "property" declared as such:

@property (nonatomic,retain,nonnull) NSString *mType;

In a instance method of this class, I can refer to mType in various ways, with warnings:

mType "Instance variable 'mType' is being directly accessed"
_mType "Use of undeclared identifier '_mType'; did you mean 'mType'?"
self.mType (No warning, but is very slow if used in a loop. Needed for blocks)


Q1: "Direct" access to an instance variable bypasses its setter/getter methods, but otherwise what is wrong with it?

Q2: Sometimes using the underscore form, _mType, quiets the direct access warning; other times Xcode acts like it doesn't know what I'm referring to. What is the underscore intended for?

Yes I can turn the Xcode warnings off by deleting -Weverything, but I want to do the right thing...

-Carl






Carl Hoefs
 

I have an ObjC class that has an instance variable "property" declared as such:

@property (nonatomic,retain,nonnull) NSString *mType;

In a instance method of this class, I can refer to mType in various ways, with warnings:

mType "Instance variable 'mType' is being directly accessed"
_mType "Use of undeclared identifier '_mType'; did you mean 'mType'?"
self.mType (No warning, but is very slow if used in a loop. Needed for blocks)


Q1: "Direct" access to an instance variable bypasses its setter/getter methods, but otherwise what is wrong with it?

Q2: Sometimes using the underscore form, _mType, quiets the direct access warning; other times Xcode acts like it doesn't know what I'm referring to. What is the underscore intended for?

Yes I can turn the Xcode warnings off by deleting -Weverything, but I want to do the right thing...

-Carl