我是Obj-C的新手,所以我的第一个问题是:
对象指针的strong
声明中weak
和@property
之间有什么区别?
此外,nonatomic
是什么意思?
答案 0 :(得分:685)
考虑气球方面的强弱参考可能会有所帮助。
只要至少有一个人抓住附着在其上的绳子,气球就不会飞走。持有字符串的人数是保留计数。当没有人抓住绳子时,气球会飞走(dealloc)。许多人可以使用同一个气球的字符串。您可以使用强引用和弱引用来获取/设置属性并在引用的对象上调用方法。
一个强大的参考就像保持一个字符串到那个气球。只要你抓住附在气球上的绳子,它就不会飞走。
弱参考就像看气球一样。你可以看到它,访问它的属性,调用它的方法,但你没有该气球的字符串。如果每个人都拿着绳子放开,那么气球就会飞走,你就再也无法进入了它。
答案 1 :(得分:627)
强引用(在大多数情况下将使用)意味着您希望“拥有”使用此属性/变量引用的对象。只要您使用强引用指向它,编译器就会注意您分配给此属性的任何对象都不会被销毁。只有将属性设置为nil
后,对象才会被销毁(除非一个或多个其他对象也拥有对它的强引用)。
相反,使用弱引用表示您不希望控制对象的生命周期。您引用弱的对象只会继续存在,因为至少有一个其他对象对它有强烈的引用。一旦不再是这种情况,对象就会被破坏,你的弱属性将自动设置为nil
。 iOS中最常见的弱引用用例是:
委托属性,通常被弱引用以避免保留周期,
视图控制器主视图的子视图/控件,因为主视图已经强烈保存了这些视图。
atomic与nonatomic是指编译器为该属性合成的getter和setter方法的线程安全性。 atomic(默认值)告诉编译器使访问器方法成为线程安全的(通过在访问ivar之前添加一个锁),而非原子操作则相反。非原子的优点是性能略高。在iOS上,Apple几乎所有属性都使用非原子,因此一般建议您也可以这样做。
答案 2 :(得分:22)
strong :为其分配传入值,它将保留传入值并释放实例变量的现有值
弱:将传入的值分配给它而不保留它。
所以基本的区别在于保留新变量。 通常你想保留它,但有些情况下你不想拥有它,否则你会得到一个保留周期而无法释放对象的内存。例如。 obj1保留obj2,obj2保留obj1。要解决这种情况,请使用弱引用。
答案 3 :(得分:12)
虚假答案: -
我认为上面的答案给出了解释,所以我要告诉你在哪里使用 STRONG
以及在哪里使用 WEAK
:
使用Weak
: -
1.代表们
2.奥特莱斯
3.子视图
4.控制等
使用Strong
: -
保留在 WEAK
中未包含的所有地方。
答案 4 :(得分:8)
强和弱,这些关键字围绕Objective-C中的对象所有权
什么是对象所有权?
指针变量意味着他们指向的对象的所有权。
只要指针变量指向一个对象,该对象就拥有一个所有者并保持活跃状态。这被称为强大引用。
变量可以选择不取得它指向的对象的所有权。不取得对象所有权的变量称为弱引用。
请在此处查看详细说明Demystifying @property and attributes
答案 5 :(得分:6)
此处, Apple文档使用各种示例解释了弱属性和强属性之间的区别:
此处,在此博客中,作者收集了同一地点的所有属性。它将有助于比较属性特征:
http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html
答案 6 :(得分:6)
强是默认值。只要存在指向它的强指针,对象就会保持“活着”。
弱指定不使引用对象保持活动状态的引用。当没有对象的强引用时,弱引用设置为nil。
答案 7 :(得分:2)
要了解强弱参考,请考虑以下示例,假设我们有一个名为displayLocalVariable的方法。
-(void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
}
在上述方法中,myName变量的作用域仅限于displayLocalVariable方法,一旦方法完成,保存字符串“ ABC”的myName变量将从内存中重新分配。
现在,如果要在整个视图控制器生命周期中保留myName变量值,该怎么办。为此,我们可以创建名为username的属性,该属性具有对变量myName的强引用(请参见下面的代码中的@property(nonatomic,strong) NSString* username;
和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具有对myName的强引用(正如我们在接口中使用@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;
}
在上面的代码中,self.username具有对myName的强引用,因此,即使方法结束后self.dummyName现在也具有myName的值,因为myName具有与其关联的强引用。
现在,只要我们对变量进行强引用,其保留计数就会增加1,并且直到iy的保留计数达到0时,变量才会被释放。
希望这会有所帮助。
答案 8 :(得分:1)
强:基本上使用我们用于从/向另一个类获取或发送数据的属性。 弱:通常所有插座,连接都是接口的弱类型。
Nonatomic :当我们不希望将我们的插座或对象分享到不同的同时线程时,会使用这种类型的属性。换句话说,Nonatomic实例使我们的属性一次处理一个线程。 希望它对你有所帮助。