iOS开发基础76-iOS 开发中的属性修饰符详解

在iOS开发中,理解属性修饰符(例如assigncopyretainweakstrong),对编写高效、健壮的代码至关重要。

属性修饰符解析

1. assign

assign适用于基础数据类型(例如NSIntegerCGFloat)和C数据类型(例如intfloatdouble)。它是最简单的赋值方式,只是进行指针赋值,不改变引用计数。

@property (nonatomic, assign) NSInteger age;

上述代码中,每次对age赋值时,只是简单的值复制,并不会引起引用计数的变化。

2. copy

copy主要用于不可变对象(尤其是NSString),它确保对象的不可变性。copy修饰符在赋值时,会创建一个新的对象副本,并将引用计数设为1。

@property (nonatomic, copy) NSString *title;

在上面的代码中,即使传入的是一个可变字符串,title属性也会被赋值为一个不可变字符串。

3. retain

retain适用于除NSString外的其他NSObject及其子类。在赋值时,会先释放旧的对象,将输入对象的引用计数加1,并把其赋值给属性。

@property (nonatomic, retain) NSObject *someObject;

注意:ARC(Automatic Reference Counting)下,retain已经被strong代替。

4. weakstrong

strong

使用strong修饰符的属性,会持有对象,即增加对象的引用计数,确保对象在其生命周期内不会被释放。

@property (nonatomic, strong) NSObject *strongObject;

weak

weak修饰符的属性,不持有对象,即不增加对象的引用计数。如果对象的最后一个strong引用指针被删除,对象会被释放,并且所有指向它的weak指针自动置为nil

@property (nonatomic, weak) NSObject *weakObject;

weakstrong 的示例

考虑一个使用weakstrong的例子:

@interface MyClass : NSObject
@property (nonatomic, strong) NSObject *dog;
@property (nonatomic, weak) NSObject *observer;
@end

@implementation MyClass
@end

strongweak 指针的区别可以比喻为牵狗和指狗:

  • strong 指针就像牵着一条狗的牵绳,只要有strong的引用存在,狗(对象)不会跑掉(不会被释放)。
  • weak 指针就像一个小孩指着狗说“看,那是一只狗”。当存在strong指针时,weak指针可以引用对象,而当狗被释放(所有strong指针消失)时,weak指针会自动变成nil

典型使用场景

  • assign: 对基础数据类型(例如NSIntegerCGFloat)以及C数据类型(例如intfloat)。
  • copy: 常用于NSString属性,以确保不可变性。
  • retain/strong: 大多数NSObject及其子类使用retain(对于ARC项目使用strong)。
  • weak: 常用于委托模式中防止循环引用(如delegate)、UI组件中的父视图引用。

nonatomicatomic

atomic

atomic是Objective-C中默认的线程保护技术,它确保属性在多线程并发访问时的安全。每次对属性进行存取操作时,都会加锁,以防止不同线程同时读写导致的数据不一致问题。不过,这会增加系统开销。

nonatomic

nonatomic禁止属性的自动线程保护,它不会加锁,提高了性能,因此在iOS开发中,常在没有多线程竞争的场景下使用。

@property (nonatomic, strong) NSString *name;

上述代码中的nonatomic属性在单线程或无并发情况下可以显著提升性能。

内存管理的底层逻辑

retainreleaseautorelease是Objective-C管理内存的基础方法。当使用ARC时,这些方法会被自动插入代码中,提高了开发效率,减少了内存泄漏的风险。

自动引用计数(ARC)

ARC在编译时会自动插入合适的retainreleaseautorelease语句,而不需要程序员手动管理。这极大地简化了内存管理的复杂性,同时也减少了内存泄漏的风险。

MyClass *obj = [[MyClass alloc] init];
// ARC 会自动插入 [obj retain];

当对象的引用计数变为0时,ARC会自动释放对象。

__block 修饰符

在Block中使用外部变量时,如果需要修改这些变量,可以使用__block修饰符。

__block int count = 0;
void (^countBlock)(void) = ^{
    count++;
};
countBlock();

__block修饰的变量可以在Block内部被修改,而非简单复制。

总结

理解属性修饰符(如assigncopyretainweakstrong)及其背后的内存管理机制,对于编写高效且健壮的iOS代码至关重要。通过ARC和这些修饰符的组合使用,开发者可以有效管理内存,避免常见的性能和内存问题,提高代码的可维护性和稳定性。

posted @ 2016-03-26 14:30  Mr.陳  阅读(287)  评论(0编辑  收藏  举报