I read this from Appledoc regarding the famous (or shameful?) init method
In some cases, the init method may return a placeholder object. Therefore, you should always use the object returned by init, and not the one returned by alloc or allocWithZone :, in the following code.
So to speak, I have these two classes
@interface A : NSObject @end @interface B : A @property (nonatomic, strong) NSArray *usefulArray; @end
with the next implementation
@implementation A +(NSMutableArray *)wonderfulCache { static NSMutableArray *array = nil; if (!array) array = [NSMutableArray array]; return array; } -(id)init { if (self=[super init]) { // substituting self with another object // A has thought of an intelligent way of recycling // its own objects if ([self.class wonderfulCache].count) { self = [self.class wonderfulCache].lastObject; [[self.class wonderfulCache] removeLastObject]; } else { // go through some initiating process // .... if (self.canBeReused) [[self.class wonderfulCache] addObject:self]; } } return self; } -(BOOL) canBeReused { // put in some condition return YES; } @end @implementation B -(id)init { if (self=[super init]) { // setting the property self.usefulArray = [NSArray array]; } return self; } @end
When B calls init , [super init] can return the replaced object A, and does it cause an error when B tries to set a property (which A does not have)?
If this causes an error, how can we correctly implement the above pattern?
Update: adding a more specific specific problem
Here's a C ++ class called C (its use will be explained later)
class C {
Let's say goal A is to act like a wrapper C ; and it is vital that a one-to-one relationship is maintained between A and C at all times .
So, I come up with the following integration and implementation
@interface A : NSObject -(id)initWithC:(C *)c; @end @implementation A { C *_c; } -(id)initWithC:(C *)c { id cu = (__bridge id) c->GetUserData(); if (cu) {
It works for now. Now I would like to subclass A , so I come up with B
@interface B : A @property (nonatomic, strong) NSArray *usefulArray; @end
Now the problem arises when A does not know how to properly untie the instance. So I need to change the above code to
@interface A : NSObject { C *_c; } -(id)initWithC:(C *)c; -(void) bind; -(void) unbind; @end @implementation A -(id)initWithC:(C *)c { id cu = (__bridge id) c->GetUserData(); if (cu) {
Now B only needs to override bind and unbind to make it work.
But when I think about it, all B wants to do is to have an additional array of usefulArray , does this really justify this most of the work ...? And the idea that the unbind entry is only for your subclass, which will replace you in a 1-to-1 relationship with a C ++ object, just seems weird (and inefficient).