Chris Muench
Chris Muench

Reputation: 18318

Is it ok to just use instance variable and NOT property

I have an instance variable apiEndpoint that I don't want to be set from anywhere except init and I only want it to be private to the class. Is it ok if I use an instance variable and NOT a property?

ApiWrapper.h

#import <Foundation/Foundation.h>

@interface ApiWrapper : NSObject
{
    NSString *apiEndpoint;
}

- (void) initWithApiEndpoint:(NSString *) newApiEndpoint;


+ (NSString *)getApiEndpoint:(NSString *) storeUrl;
+ (NSString *)getApiEndpointWithoutIndexDotPHP:(NSString *) storeUrl;
@end

ApiWrapper.m

#import "ApiWrapper.h"


@implementation ApiWrapper
- (void) initWithApiEndpoint:(NSString *) newApiEndpoint;
{
    apiEndpoint = newApiEndpoint;
}
+ (NSString *)getApiEndpoint:(NSString *) storeUrl
{
    if (![storeUrl hasPrefix:@"http://"] && ![storeUrl hasPrefix:@"https://"])
    {
        NSLog(@"%@ missing http", storeUrl);
    }

    return nil;
}

+ (NSString *)getApiEndpointWithoutIndexDotPHP:(NSString *) storeUrl
{

}

@end

Upvotes: 2

Views: 84

Answers (3)

foundry
foundry

Reputation: 31745

See my answer here:
Should I declare variables in interface or using property in objective-c arc?

The summary version:

  • whenever possible, declare properties
  • don't declare iVars separately
  • don't @synthesize
  • locate as few properties as possible in you .h file
  • locate as many properties as possible in a class extension in your .m file

The only other point I would add - if for whatever reason you are going to use iVars, please use a clear convention like _leading _underscores so that we know what you are doing when we read your code.

Upvotes: 2

Rob
Rob

Reputation: 437622

I agree with claireware's suggestion to use a private property in your private class extension. Another approach, if you want other classes to be able to see it, but not alter it, is to define it as a read only property:

In ApiWrapper.h:

#import <Foundation/Foundation.h>

@interface ApiWrapper : NSObject

@property (nonatomic, strong, readonly) NSString *apiEndpoint;

- (id) initWithApiEndpoint:(NSString *) newApiEndpoint;

+ (NSString *)getApiEndpoint:(NSString *) storeUrl;
+ (NSString *)getApiEndpointWithoutIndexDotPHP:(NSString *) storeUrl;

@end

And in ApiWrapper.m:

#import "ApiWrapper.h"

@interface ApiWrapper ()

@property (nonatomic, strong) NSString *apiEndpoint;

@end

@implementation ApiWrapper

- (id) initWithApiEndpoint:(NSString *) newApiEndpoint;
{
    self = [super alloc];
    if (self)
    {
        _apiEndpoint = newApiEndpoint;
    }

    return self;
}

@end

Two notes:

  1. The init... method should not have a void return type. init methods should always return an initialized object.

  2. If you use properties, remember to Don’t Use Accessor Methods in Initializer Methods and dealloc.


Obviously, if you really wanted to use an ivar (and I agree with others that you can achieve what you want with a property), it would simply be:

ApiWrapper.h:

#import <Foundation/Foundation.h>

@interface ApiWrapper : NSObject

- (id) initWithApiEndpoint:(NSString *) newApiEndpoint;

+ (NSString *)getApiEndpoint:(NSString *) storeUrl;
+ (NSString *)getApiEndpointWithoutIndexDotPHP:(NSString *) storeUrl;

@end

And in ApiWrapper.m:

#import "ApiWrapper.h"

@interface ApiWrapper ()
{
    NSString *apiEndpoint;
}
@end

@implementation ApiWrapper

- (id) initWithApiEndpoint:(NSString *) newApiEndpoint;
{
    self = [super alloc];
    if (self)
    {
        apiEndpoint = newApiEndpoint;
    }

    return self;
}

@end

Upvotes: 2

kamprath
kamprath

Reputation: 2308

Yes, it's OK to use ivars. However, what is cool about properties is that they create your getter and setter for you, which are more than just reading or writing a variable value but can include things like object retain management, thread-safe read and writes, and more.

There is a way to make a "private property" by declaring it in an anonymous class extension in your class's .m file. Note you will still have to use the ivar backing the property in the init and dealloc method. Your code would look something like this:

#import "ApiWrapper.h"

@interface ApiWrapper ()
@property (strong,nonatomic) NSString* apiEndpoint;

@end

@implementation ApiWrapper

- (id) initWithApiEndpoint:(NSString *) newApiEndpoint;
{
    self = [super init]
    if ( self ) {
        _apiEndpoint = newApiEndpoint;
    }

    return self;
}

Upvotes: 4

Related Questions