@property的参数(1)

在OC的内存管理中,如果忘记释放OC对象,很有可能就造成内存泄露。为了避免忘记释放内存,我们通常在setter方法中释放类属性中的OC对象,这也使得代码过于麻烦。好在@property的参数解决了这个问题。

本文将讲解常用的@property参数含义,以及与它等效的代码实现。

环境信息:

Mac OS X : 10.9

Xcode : 5.1.1

正文:

一. 首先,@property都有哪些常用参数

property参数列表
property参数列表

除了这些,还有getter和setter等,将在下面做讲解。

二. 详细讲解

1. readwrite / readonly

系统默认值为:readwrite。


@property (readwrite) int age;

等价于:


@property int age;

等价于:


- (void) setAge : int newAge {

   _age = newAge;
}

- (int) getAge {

   return _age;
}

如果设置属性只读:


@property (readonly) int age;

等价于:


- (int) getAge {

   return _age;
}

2. assign / retain / copy

这对参数主要用于OC对象释放的时候。assign是在setter时,直接赋值,没有额外操作,而retain则需要先释放旧的对象,再赋值。

对基本类型(int char …)进行retain是错误的。


@property (assign) classA *a;

等价于:


@property classA *a;

等价于:


- (void) setA : (classA *) newA {

   _a = newA;
}

- (classA *) getA {

   return _a;
}

但是这种实现方式,很有可能造成内存泄露(对象没有完全释放)这种问题。oc也给我们提供了一种安全的setter方式,就是使用retain参数,这样也避免了自己敲在setter中释放内存这段代码。


@property (retain) classA *a;

等价于:


- (void) setA : (classA *) newA {

  if (_a != newA) {
  
     [_a release];
     _a = newA;
  }
}

- (classA *) getA {

  return _a;
}

所以在声明OC对象的时候,更建议直接使用retain参数,避免自己重复在setter中写释放内存的代码。

copy参数会在setter中copy对象,与retain类似


@property (copy) classA *a;

等价于:


- (void) setA : classA *newA {

   if (_a != newA) {

      [_a release];
      _a = [newA copy]
   }
}

3. atomic / nonatomic

这对参数用于线程是否安全。atomic线程安全,nonatomic线程不安全。

虽然线程安全可以防止出现死锁,但是效率却降低了。所以,在开发过程中,用得最多的还是nonatomic参数。


@property classA *a;

等价于


@property (atomic) classA *a;

等价于:


- (classA *) getA {

    [_a retain];
    return [_a autorelease];
}

线程不安全的情况:


@property ?(nonatomic) classA *a;

等价于:


- (classA *) getA {

    return _a;
}

发表评论

电子邮件地址不会被公开。