iPhone – How to write a correct readOONLY attribute?

I have two questions about how to create correct read-only attributes in Objective-C 2.0.

This is my original method, we Call it solution 1:

@interface ClassA{
@private
NSMutableArray *a_;
}

// NOTE: no retain
@property (nonatomic, readonly) NSMutableArray *a;

@end


///// ////////////////////////////////
@implementation ClassA

@ synthesize a = a_;

- (NSMutableArray *)a{
if(nil == a_){
a_ = [[NSMutableArray alloc] array];
}
// Potential leak warning on the following line.
return a_;
}

- (void)dealloc{
// I released the object here, I think this should be safe.
[a_ release];
[super dealloc];
@end

When I compile and analyze it, the system Will report this warning: “A leak may occur when returning to a_'”.

Then I read the Objective-C documentation again and found another way, as shown below. We call it the solution 2.

@interface ClassB{
@private
NSMutableArray *a_;
}

// NOTE : make it retain+readonly
@property (non atomic, readonly, retain) NSMutableArray *a;

@end


////////////////// ////////////////////
// Add a private category
@interface ClassB ()

// reset the property to readwrite
@property (nonatomic, readwrite, retain) NSMutableArray *a;

@end

//////
@implementation ClassB

@synthesize a = a_;

- (id)init{
if(self = [super init]){
/ / NOTE: set the value as we use property normally.
self.a = [NSMutableArray array];
}
return self;
}

-(void)dealloc{
self.a = nil;
[super dealloc];
@end

Now, this is my problem:

>Is it possible to use solution 1 and get rid of “potential leaks”?
>Is Solution 2 a common solution?

Thank you!

– Downey

Upon request, I’m copying my comment as Answer:

[[NSMutableArray alloc] array] should give you a compiler warning, it will definitely crash. You want [[NSMutableArray alloc] init].

I have two questions about how to create correct read-only properties in Objective-C 2.0.

This is my original method, which we call Solution 1:

@interface ClassA{
@private
NSMutableArray *a_;
}

/ / NOTE: no retain
@property (nonatomic, readonly) NSMutableArray *a;

@end


//////// //////////////////////////////
@implementation ClassA

@synthesize a = a_;

- (NSMutableArray *)a{
if(nil == a_){
a_ = [[NSMutableArray alloc] array];
}
// Potential leak warning on the following line.
return a_;
}

- (void)dealloc{
// I released the object here, I think this should be safe.
[a_ release];
[super dealloc];
@end

When I compile and analyze it, the system will report this Warning: “A leak may occur when returning to a_'”.

Then I read Objective again -C documentation and find another way as shown below. Let’s call it solution 2.

@interface ClassB{
@private
NSMutableArray *a_;
}

// NOTE: make it retain+readonly
@property (nonatomic, readonly, retain) NSMutableArray *a;
< br />@end


//////////////////////////////// //////
// Add a private category
@interface ClassB ()

// reset the property to readwrite
@property (nonatomic, readwrite , retain) NSMutableArray *a;

@end

//////
@implementation ClassB

@synthesize a = a_;

- (id)init{
if(self = [super init]){
// NOTE: set the value as we use property normally.
self.a = [NSMutableArray array];
}
return self;
}

- (void)dealloc{
self.a = nil ;
[super dealloc];
@end

Now, this is my question:

>Is it possible to use solution 1 and get rid of “potential leak “?
>Is Solution 2 a common solution?

Thank you!

– Downey

As requested, I am copying my comment as an answer:

[[NSMutableArray alloc] array] should give you a compiler warning, it will definitely crash. You want [[NSMutableArray alloc] init].

Leave a Comment

Your email address will not be published.