How to write the correct readonly property?

I have 2 questions on how to make the readonly property correct in Objective-C 2.0 +.

Here is my original approach, call him 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 reports this warning: "potential leak in" return a _ ".

Then I read the Objective-C document again and found a different approach, as shown below. Call it solution 2 .

@interface ClassB{
 @private
  NSMutableArray *a_;
}

// NOTE: make it retain+readonly
@property (nonatomic, 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 here are my questions:

  • Is it possible to use solution 1 and get rid of the "potential leak"?
  • Does decision 2 solve the general solution?

Thanks guys!

- Ton

+3
source share
3 answers

:

[[NSMutableArray alloc] array] , . [[NSMutableArray alloc] init].

+3

, , init.

, , - :

@interface ClassA{
 @private
  NSMutableArray a_;
}

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

@end

@implementation ClassB

@synthesize a = a_;

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

- (NSMutableArray *)a
{
 return a_;
}

- (void)dealloc{
    [a_ release];
    [super dealloc];
   }
@end

:

a_.

+2

, "private" - :

MyClass.h

@interface MyClass : NSObject

@property (nonatomic, copy, readonly) NSArray * someArray;    // Public

@end

MyClass.m

@interface MyClass ()     // Class extension

@property (nonatomic, copy, readwrite) NSArray * someArray;   // "Private"

@end

@implementation MyClass

@synthesize someArray = someArray_;

- (id)init
{
    self = [super init];

    if (self != nil)
    {
        self.someArray = ...; // Array initialization
    }

    return self;
}

- (void)dealloc
{
    [someArray_ release];

    [super dealloc];
}

@end

! . (, ), -, .

(Of course, I still declare an explicit ivar synthesis - in this example someArray_- for use in -dealloc, since there are good reasons not to use the properties in -deallocand, possibly, in -init).

+2
source

Source: https://habr.com/ru/post/1790622/


All Articles