copy
之外,请问strong
与retain
、weak
与assign
之间有什么区别吗?根据我的理解,唯一的差别在于weak
将指针分配为nil
,而assign
则不会这样做,这意味着一旦释放后向该指针发送消息就会导致程序崩溃。但如果我使用weak
,这种情况永远不会发生,因为发送到nil
的消息不会执行任何操作。关于strong
与retain
我不知道是否有任何区别。在新项目中,是否应该使用assign
和retain
,或已经被淘汰了?copy
之外,请问strong
与retain
、weak
与assign
之间有什么区别吗?根据我的理解,唯一的差别在于weak
将指针分配为nil
,而assign
则不会这样做,这意味着一旦释放后向该指针发送消息就会导致程序崩溃。但如果我使用weak
,这种情况永远不会发生,因为发送到nil
的消息不会执行任何操作。关于strong
与retain
我不知道是否有任何区别。在新项目中,是否应该使用assign
和retain
,或已经被淘汰了?在阅读了许多文章、Stackoverflow帖子和演示应用程序以检查变量属性特性之后,我决定将所有属性信息整合在一起:
以下是详细的文章链接,您可以在其中找到上述所有属性,这肯定会对您有所帮助。非常感谢在这里给出最佳答案的所有人!!
1.strong (iOS4 = retain )
例如:
@property (strong, nonatomic) ViewController *viewController;
@synthesize viewController;
2.弱引用 -
例如:
@property (weak, nonatomic) IBOutlet UIButton *myButton;
@synthesize myButton;
强引用与弱引用的解释,感谢BJ Homer提供的解答:
假设我们的对象是一只狗,并且这只狗想要逃跑(被释放)。
强引用就像是一条绳子拴在狗上面。只要你把绳子系在狗身上,狗就不会逃跑。如果有五个人把他们的绳子都系在同一只狗上(即五个强引用指向同一个对象),那么直到这五个绳子全部解除之前,狗都不会逃跑。
另一方面,弱引用就像是一些小孩子指着狗说“看,一只狗!”只要狗还被系在绳子上,小孩子们就可以看到狗,并且继续指着它。但是,一旦所有的绳子都被解除,无论有多少小孩子指着它,狗都会逃走。
当最后一个强引用(绳子)不再指向一个对象时,该对象将被销毁,所有的弱引用也将被清零。
我们何时使用弱引用?
唯一需要使用弱引用的情况是,如果你想避免循环引用(例如父对象保留子对象,而子对象也保留父对象,这样两个对象都不会被释放)。
3.retain = strong
示例:
@property (nonatomic, retain) NSString *name;
@synthesize name;
4.assign
示例:
@property (nonatomic, assign) NSString *address;
@synthesize address;
default
是什么意思?如果我使用 @property (nonatomic) NSString *string
,它是 strong
吗?还是 assign
?因为两者都是默认设置。 - Iulian Onofrei来自过渡到ARC发布说明(属性特性部分的示例)。
// The following declaration is a synonym for: @property(retain) MyClass *myObject;
@property(strong) MyClass *myObject;
因此,在属性声明中,strong
和 retain
是相同的。
对于 ARC 项目,我会使用 strong
而不是 retain
,我会对 C 原始类型属性使用 assign
,并对 Objective-C 对象的弱引用使用 weak
。
assign
来声明一个对象类型的属性会导致编译错误。如果你不想对该属性进行 retain 操作,你需要使用 weak
或 unsafe_unretained
(显然是不安全的)来声明。 - cobbalassign
编译得非常好。 - Pascalassign
在某些情况下仍然有效的观点。 - Steven Oxleystrong
和 retain
是同义词,所以它们的作用是完全相同的。weak
几乎像是 assign
,但在所指向的对象被释放后自动设置为 nil。assign
而不是weak
。假设我们有两个属性 delegateAssign
和 delegateWeak
,都存储了拥有我们唯一强引用的委托。当委托被释放时,我们的 -dealloc
方法也会被调用。// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
[delegateWeak doSomething];
[delegateAssign doSomething];
}
代表对象已经在解除分配过程中,但仍未完全解除分配。问题在于weak
引用已经被置为null了! 属性delegateWeak
包含nil,但delegateAssign
包含一个有效的对象(所有属性已释放和置null,但仍然有效)。
// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
[delegateWeak doSomething]; // Does nothing, already nil.
[delegateAssign doSomething]; // Successful call.
}
这是一个非常特殊的情况,但它向我们展示了这些弱
变量如何工作以及何时被置空。
有四个所有权限定符:
- __autoreleasing
- __strong
- __*unsafe_unretained*
- __weak
如果类型被限定为 __autoreleasing, __strong, 或者 __weak,则该类型是非平凡的所有权限定。
然后对于已声明属性,有六个所有权修饰符:
- assign 意味着 __*不安全的非保留(unsafe_unretained)* 所有权。
- copy 意味着 __强烈的(strong) 所有权,以及 setter 上拷贝语义的常规行为。
- retain 意味着 __强烈的(strong) 所有权。
- strong 意味着 __强烈的(strong) 所有权。
- *unsafe_unretained* 意味着 __*不安全的非保留(unsafe_unretained)* 所有权。
- weak 意味着 __弱引用(weak) 所有权。
除了 weak 外,这些修饰符在非 ARC 模式下可用。
从语义上讲,在五个管理操作:读取、赋值、初始化、销毁和移动中,所有权限定符具有不同的含义,在大多数情况下我们只关心赋值操作的差异。
在评估分配运算符时会发生分配。其语义因资格而异: -(void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
}
在上面的方法中,myName变量的作用域仅限于displayLocalVariable方法,一旦该方法完成,持有字符串“ABC”的myName变量将从内存中被释放。
现在,如果我们想要在整个视图控制器生命周期内保留myName变量的值。为此,我们可以创建名为username的属性,它将对变量myName具有强引用(请参见下面代码中的self.username = myName;
),如下所示:
@interface LoginViewController ()
@property(nonatomic,strong) NSString* username;
@property(nonatomic,weak) NSString* dummyName;
- (void)displayLocalVariable;
@end
@implementation LoginViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated
{
[self displayLocalVariable];
}
- (void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
self.username = myName;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
@end
在上面的代码中,你可以看到myName已经被分配给了self.username,并且self.username使用@property在接口中声明了一个强引用(间接地,它拥有对“ABC”字符串的强引用)。因此,在self.username存在的情况下,字符串myName将不会从内存中释放。
现在考虑将myName分配给一个弱引用dummyName,即self.dummyName = myName;与强引用不同,弱引用只会持有myName,直到myName有强引用为止。请参见下面的代码以了解弱引用:
-(void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
self.dummyName = myName;
}
在上述代码中,对于myName存在弱引用(即self.dummyName具有myName的弱引用),但是没有强引用指向myName,因此self.dummyName将无法持有myName的值。
现在再考虑下面的代码:
-(void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
self.username = myName;
self.dummyName = myName;
}
示例: @property (strong, nonatomic) ViewController *viewController;
@synthesize viewController;
默认情况下自动获取并设置为nil。
示例: @property (weak, nonatomic) IBOutlet UIButton *myButton;
@synthesize myButton;
strong
、weak
和unsafe_unretained
。您可以使用这些属性来指定对象属性在被引用时如何保持和释放内存。 - NJonesweak
和strong
)和4个变量生命周期限定符(__strong
、__weak
、__unsafe_unretained
、__autoreleasing
)。请参见下面的ARC注释。 - Snowcrashassign
编译ARC时会出现错误。有许多已删除的答案涉及此问题。似乎在最终发布之前已经更改了这一点。对于我们这些早期采用者来说,unsafe_unretained
是首选属性。要证明unsafe_unretained
是有效属性,请查看苹果公司的“Objective-C编程”手册,在“封装数据”部分下的“对某些类使用不安全的未保留引用”小节中。其中写道:“对于属性,这意味着使用unsafe_unretained
属性:”。 - NJones