English 中文(简体)
如何编写正确的只读属性?
原标题:How to write a correct readonly property?

关于如何在Objective-C 2.0+中生成正确的只读属性,我有两个问题。

这是我最初的方法,让我们称之为解决方案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

当我编译和分析它时,系统会报告这样的警告:“返回a_时可能发生泄漏”。

然后我再次阅读了Objective-C的文档,发现了另一种方法如下。让我们称之为解决方案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

现在,我的问题如下:

  • Is it possible to use solution 1 and get rid of potential leak ?
  • Does solution 2 the common solution?

谢谢你们!

--托尼

最佳回答

应要求,我转载我的评论作为答复:

[[NSMutableArray alloc]array]应该向您发出编译器警告,它肯定会崩溃。您需要[[NSMutableArray alloc]init]

问题回答

老实说,我发现只使用“私人”读写属性而不必对ivar大惊小怪更容易:

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

不需要ivar!现代运行库将自动合成它们。您的属性在外部(即其他类)是只读的,但在内部,您已将该属性重新声明为读写,因此您可以利用合成属性访问器的便利性。

(当然,我在这个例子中仍然声明了一个显式的ivar合成,someArray_-用于-dealloc,因为有充分的理由不在-dalloc中使用属性,也可能不在-init中使用。)

一般来说,如果现在只读属性的值将提前,那么最好在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)。





相关问题
Code sign Error

I have created a new iPhone application.I have two mach machines. I have created the certificate for running application in iPhone in one mac. Can I use the other mac for running the application in ...

ABPersonViewController Usage for displaying contact

Created a View based Project and added a contact to the AddressBook using ABAddressBookRef,ABRecordRef now i wanted to display the added contact ABPersonViewController is the method but how to use in ...

将音频Clips从Peter改为服务器

我不禁要问,那里是否有任何实例表明从Peit向服务器发送音响。 I m不关心电话或SIP风格的解决办法,只是一个简单的袖珍流程......

• 如何将搜查线重新定位?

我正试图把图像放在搜索条左边。 但是,问题始于这里,搜索条线不能重新布署。

热门标签