I know it's not a great idea to try and place properties in a category. Can I access a class' instance variables from within a category that extends it? Or is it necessary to expose an accessor on the class being extended?
For example, let's say I have a class called "Person" and its implementation looks like this:
#import "Person.h"
@interface Person()
{
NSMutableArray *_friends;
}
@end
@implementation Person
- (instancetype)init
{
self = [super init];
if (self) {
_friends = [NSMutableArray array];
}
return self;
}
-(instancetype)initWithFirstname:(NSString *)firstName lastname:(NSString *)lastName
{
self = [self init];
if (self) {
_firstName = firstName;
_lastName = lastName;
}
return self;
}
-(NSString *)getFullName{
return [NSString stringWithFormat:@"%@ %@", _firstName, _lastName];
}
@end
Notice the ivar _friends
. Let's say (for some reason or other) I wanted to segregate all operations dealing with a person's friends into a category, like so:
#import "Person.h"
@interface Person (Friends)
-(NSArray *)getFriends;
-(void)addFriend:(Person *)person;
-(void)removeFriend:(Person *)person;
@end
In the category, Person(Friends)
, the compiler will not know about Person
's ivar _friends
.
i.e.
//Person.h
@interface Person
@property(nonatomic, strong) NSMutableArray *friends;
...
@end
It would be preferable to not expose this.
Category and extension both are basically made to handle large code base, but category is a way to extend class API in multiple source files while extension is a way to add required methods outside the main interface file.
It has many copies so every object has its own personal copy of the instance variable. It has only one copy of the class variable so it is shared among different objects of the class. It can be accessed directly by calling variable names inside the class. It can be accessed by calling with the class name.
Instance Variable cannot have a Static modifier as it will become a Class level variable. Meaning STATIC is one of the keyword which cannot be used with Instance variable.
Instance variables are declared in a class, but outside a method, constructor or any block. When space is allocated for an object in the heap, a slot for each instance variable value is created.
In general, categories can't access ivars; synthesized ivars and ivars from class extensions are private and invisible outside the main implementation.
You can, however, do what you want by declaring the ivar in an extension which is in its own private header, and importing that header into the category's implmentation file. Be sure to also import the private header into the class's main implementation file.
Who have told you that the compiler will not know about Person
's _friends
?
It knows. Just declare _friends
in the class @interface
, not in an extension.
@interface Person : NSObject
{
@protected
NSMutableArray *_friends;
}
@end
With @protected
_friends
will not be accessible for other objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With