pvllnspk
pvllnspk

Reputation: 5767

private fields on Objective C

What is difference of these three cases (all of them are used like private fields):

1.

@interface APLParseOperation : NSOperation

@property (copy, readonly) NSData *earthquakeData;

@end

2.

@interface APLParseOperation () <NSXMLParserDelegate>

@property (nonatomic) APLEarthquake *currentEarthquakeObject;
@property (nonatomic) NSMutableArray *currentParseBatch;
@property (nonatomic) NSMutableString *currentParsedCharacterData;

@end

3.

@implementation APLParseOperation
{
    NSDateFormatter *_dateFormatter;
    BOOL _accumulatingParsedCharacterData;
    BOOL _didAbortParsing;
    NSUInteger _parsedEarthquakesCounter;
}

It's a good practice or smthing else?

Upvotes: 2

Views: 202

Answers (4)

Zedenem
Zedenem

Reputation: 2559

Case 1. is not private. It's a public read-only property: Reading is public, writing is only possible only in the private scope via the underlying ivar (thanks for pointing it out @mah).

Case 2. (if in a .m file) is extending the class by adding 3 private properties and making the protocol conformance private too.

Case 3. is declaring 4 private instance variables that can be used in all the implementation scope.

Objective-C best practice for private properties is case 2., as case 1. is not private at all, just read-only, and case 3. uses instance variables (aka ivar) which is less conventional than properties. More on that here: Reason to use ivars vs properties in objective c

Hope this helps,

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726559

  1. defines a public property visible to all users of the APLParseOperation class.
  2. defines properties through an extension, making them available only to the implementation methods.
  3. defines instance variables which are implicitly private.

Number 1 is used when you want to make your properties public. Numbers 2 and 3 are for private properties and instance variables. You can also declare instance variables in class extensions, like this:

@interface APLParseOperation () <NSXMLParserDelegate>
{
    NSDateFormatter *_dateFormatter;
    BOOL _accumulatingParsedCharacterData;
    BOOL _didAbortParsing;
    NSUInteger _parsedEarthquakesCounter;
}
@end

There is not much difference between that and the number 3. It is a good idea to pick one style, and stick to it in all your code.

Upvotes: 1

user3344977
user3344977

Reputation: 3604

I'm going to go through each example you gave, and describe them. I was just having trouble with this yesterday so I feel your pain.

1.

@interface APLParseOperation : NSOperation

@property (copy, readonly) NSData *earthquakeData;

@end

By using the @property keyword, the compiler automatically synthesizes your accessor methods for you, and also a backing instance variable. However, because you are using the readonly property attribute, the compiler is only synthesizing a getter method for you.

2.

@interface APLParseOperation () <NSXMLParserDelegate>

@property (nonatomic) APLEarthquake *currentEarthquakeObject;
@property (nonatomic) NSMutableArray *currentParseBatch;
@property (nonatomic) NSMutableString *currentParsedCharacterData;

@end

This second example is very similar to the first. However, because none of them have the readonly property attribute, they will all have getters and setter methods synthesized for them, as well as the backing instance variable.

3.

@implementation APLParseOperation
{
    NSDateFormatter *_dateFormatter;
    BOOL _accumulatingParsedCharacterData;
    BOOL _didAbortParsing;
    NSUInteger _parsedEarthquakesCounter;
}

For this last example, you are just declaring instance variables. These are also private to your implementation file, where as the other 2 examples had declarations being made in your classes interface file.

No setter or getter methods are being synthesized for you by the compiler. You are simply declaring some instance variables.

In terms of private and public, your first and second examples both provide declarations that will be visible to other classes, as long as they import the current class's header file. The first example however, only provides a way to "get" the property and read it, there is no setter method because you used the readonly property attribute. With the second example, outside classes will be able to access your getter and setter methods for your property, so they can read and write.

For the third example, these are just instance variables and they are private to your class's implementation file. Basically, no outside classes will even know that they exist.

Upvotes: 2

Neal Ehardt
Neal Ehardt

Reputation: 10954

  1. This is not private. It is still readable by outside classes, though it can't be written.
  2. Private properties. It can be useful if you want to write custom getters and setters. If you are not using ARC, it can be helpful for memory management.
  3. Private members. This is my favorite. It's easy to read and easy to write.

Upvotes: 1

Related Questions