Reputation: 18318
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
Reputation: 31745
See my answer here:
Should I declare variables in interface or using property in objective-c arc?
The summary version:
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
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:
The init...
method should not have a void
return type. init
methods should always return an initialized object.
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
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