Reputation: 42622
I am learning object-c by reading a book. When I read the chapter about class extension, the book gives the following example code:
// A class extension
@interface BNREmployee ()
@property (nonatomic) unsigned int officeAlarmCode;
@end
@implementation BNREmployee
...
@end
The book says objects that are not instances of BNREmployee
can no longer see this property officeAlarmCode
. It makes an example:
BNREmployee *mikey = [[BNREmployee alloc] init];
unsigned int mikeysCode = mikey.officeAlarmCode;
This attempt would result in a compiler error that reads “No visible @interface declares the instance method officeAlarmCode”.
But I get confused. I mean I feel the book's words & its example code are contradictory. Book says objects that are not instance of BNREmployee
can not longer see property officeAlarmCode
. But in the example code above, isn't mikey
an instance of BNREmployee
? Why it cannot see officeAlarmCode
event it is an instance of BNREmployee
?
=== UPDATE =====
The book I am reading is this one. Chapter 22, page 162.
I just want to verify that the book explained in a misleading way & I am looking for a clear explanation here. Because book says "objects that are NOT instance of BNREmployee
can no longer see property officeAlarmCode", for the book reader like me, I feel it hints objects that are instance of BNREmployee
CAN SEE property officeAlarmCode
. That's why I am confusing, because mikey
is an instance of BNREmployee
but it can't access officeAlarmCode.
Upvotes: 2
Views: 13376
Reputation: 12023
As per the Apple Docs 1. a class extension can add its own properties and instance variables to a class 2. Class extensions are often used to extend the public interface with additional private methods or properties for use within the implementation of the class itself.
so if you declare the property in class extension it will be visible only to the implementation file. like
in BNREmployee.m
@interface BNREmployee ()
@property (nonatomic) unsigned int officeAlarmCode;
@end
@implementation BNREmployee
- (void) someMethod {
//officeAlarmCode will be available inside implementation block to use
_officeAlarmCode = 10;
}
@end
If you want to use officeAlarmCode in other classes, let's say OtherEmployee class then you need to create officeAlarmCode property in BNREmployee.h file with readOnly or readWrite access. Then you can use it like
BNREmployee.h
@property (nonatomic, readOnly) unsigned int officeAlarmCode; //readOnly you can just read not write
in OtherEmployee.m
import "BNREmployee.h"
@interface OtherEmployee ()
@property (nonatomic) unsigned int otherAlarmCode;
@end
@implementation OtherEmployee
you can create instance of BNREmployee
and can assign officeAlarmCode
value to otherAlarmCode
property like below
BNREmployee *bnrEmployee = [BNREmployee alloc] init];
_otherAlarmCode = bnrEmployee.officeAlarmCode;
Upvotes: 3
Reputation: 132
BNREmployee *mikey = [[BNREmployee alloc] init];
unsigned int mikeysCode = mikey.officeAlarmCode;
Upvotes: 1
Reputation: 930
What I got from it is that the property officeAlarmCode
is only visible within the BNREmployee.m
file, it will not be accessible from main.m
.
To pass the value to mikeysCode
you would have to create a method that returns officeAlarmCode
.
Upvotes: 0
Reputation: 8944
Think contexts, any other class can access the properties declared at the extensions or any categories as far as the extended interfaces are "visible" at the given context.
For example, the following implementation file contains implementation of two interfaces: BaseObject
and BaseObjectController
. At the implementation of the other class (BaseObjectController
) you can safely use the "hidden" property via getters and setters because the declaration interface is "visible". If you move the implementation of BaseObjectController
to another file that can't see declaration of the extension - this code won't compile.
#import "BaseObject.h"
#import "BaseObjectController.h"
// BaseObject
@interface BaseObject()
@property (strong) NSString * idString;
@end
@implementation BaseObject
@end
// BaseObjectController
@implementation BaseObjectController
- (void) initBaseObject {
BaseObject * bo = [BaseObject new];
bo.idString = @"01234";
}
@end
Upvotes: 0
Reputation: 16660
It is a little bit misleading to say "objects can no longer see". Objects doesn't see anything, even in the figurative sense. Let`s say: Code placed outside the implementation of the class cannot see the property.
Upvotes: 2
Reputation: 150615
Mikes is an instance of BNREmployee. But the example is telling you that the property officeAlarmCode
is not exposed and can only be used by BNREmployee objects internally.
Upvotes: 4