简体   繁体   English

iOS ARC - 弱而强的属性

[英]iOS ARC - weak and strong properties

I'm trying to understand the way ARC works, and as far as I know, I should be doing something wrong here. 我试图了解ARC的工作方式,据我所知,我应该在这里做错事。 This is the code I'm using: 这是我正在使用的代码:

Interface: 接口:

@interface ViewController : UIViewController{

}

@property (strong, nonatomic) NSString * myString ; 
@property (weak, nonatomic) NSString * myPointer ;

Implementation: 执行:

 - (void)viewDidLoad{

     [super viewDidLoad];
     self.myString = @"Hello world!" ; // myString is strong
     self.myPointer = self.myString ; // myPointer var is weak

     [self performSelector:@selector(makeNilMyValue) withObject:nil afterDelay:1];    
     [self performSelector:@selector(printValues) withObject:nil afterDelay:2];    
}

 - (void) makeNilMyValue{
     self.myString = nil ; 
}

 - (void) printValues{
     NSLog(@"myString: %@", self.myString) ;
     NSLog(@"myPointer: %@", self.myPointer) ; 
 }

After executing this, I get: 执行此操作后,我得到:

2012-02-26 11:40:41.652 test1[933:207] myString: (null)

2012-02-26 11:40:41.653 test1[933:207] myPointer: Hello world!

If I'm not wrong, due to myPointer is weak, it shouldn't retain the content of the object. 如果我没错,由于myPointer很弱,它不应该保留对象的内容。 So, it should show nil instead of "Hello World!". 所以,它应该显示nil而不是“Hello World!”。

What am I doing wrong? 我究竟做错了什么?

Following Caleb's answer, I have created another weak pointer, see code below: 在Caleb的回答之后,我创建了另一个弱指针,请参阅下面的代码:

- (void)viewDidLoad{
    [super viewDidLoad];
    self.myString = @"Hello world!" ; // myString is strong
    self.myPointer = self.myString ; // myPointer var is weak
    self.myPointer2 = self.myString ; // myPointer2 var is weak

    [self performSelector:@selector(makeNilMyValue) withObject:nil afterDelay:1];    
    [self performSelector:@selector(printValues) withObject:nil afterDelay:2];    
}

- (void) makeNilMyValue{
    self.myPointer2 = @"value changed!" ;
    self.myString = nil ;

}

- (void) printValues{
    NSLog(@"myString: %@", self.myString) ;
    NSLog(@"myPointer: %@", self.myPointer) ;
}

The point is that I still got the same answer I used to have: 关键是我仍然得到了以前的答案:

2012-02-26 12:08:13.426 test1[1333:207] myString: (null)
2012-02-26 12:08:13.427 test1[1333:207] myPointer: Hello world!

As Caleb pointed out, using a constant NSString for this example is not a good idea. 正如Caleb指出的那样,在这个例子中使用常量NSString并不是一个好主意。

The simplest way to create a string object in source code is to use the Objective-C @"..." construct: 在源代码中创建字符串对象的最简单方法是使用Objective-C @“...”构造:

NSString *temp = @"/tmp/scratch"; NSString * temp = @“/ tmp / scratch”; Note that, when creating a string constant in this fashion, you should avoid using anything but 7-bit ASCII characters. 请注意,以这种方式创建字符串常量时,应避免使用除7位ASCII字符之外的任何内容。 Such an object is created at compile time and exists throughout your program's execution. 这样的对象是在编译时创建的,并且在整个程序的执行过程中都存在。 The compiler makes such object constants unique on a per-module basis, and they're never deallocated, though you can retain and release them as you do any other object. 编译器使这些对象常量在每个模块的基础上是唯一的,并且它们永远不会被释放,尽管您可以像执行任何其他对象一样保留和释放它们。 You can also send messages directly to a string constant as you do any other string: 您还可以像执行任何其他字符串一样将消息直接发送到字符串常量:

BOOL same = [@"comparison" isEqualToString:myString]; BOOL same = [@“comparison”isEqualToString:myString];

The documentation explains that constant strings will never disappear. 文档解释了常量字符串永远不会消失。

Try using something else for your experiment. 尝试使用其他东西进行实验。 I tried NSObject and it produced expected results. 我尝试了NSObject,它产生了预期的结果。

Interface: 接口:

@interface ViewController : UIViewController

@property (strong, nonatomic) NSObject * myString; 
@property (weak, nonatomic) NSObject * myPointer;

@end

Implementation: 执行:

@implementation ViewController

@synthesize myString = _myString;
@synthesize myPointer = _myPointer;

- (void)viewDidLoad{

    [super viewDidLoad];

    self.myString = [[NSObject alloc] init];
    self.myPointer = self.myString;
    self.myString = nil; 
    NSLog(@"myString: %@", self.myString);
    NSLog(@"myPointer: %@", self.myPointer);
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

Weak pointers are set to nil when there are no strong pointers to the memory as explained in the documentation - Apple Developer or llvm . 当没有强大的内存指针时,弱指针被设置为nil,如文档中所述 - Apple Developerllvm

__weak specifies a reference that does not keep the referenced object alive. __weak指定不使引用对象保持活动状态的引用。 A weak reference is set to nil when there are no strong references to the object. 当没有对象的强引用时,弱引用设置为nil。

So, it should show nil instead of "Hello World!". 所以,它应该显示nil而不是“Hello World!”。

Constant strings are never deallocated, so your `@"Hello World!" 常量字符串永远不会被释放,所以你的`@“Hello World!” never goes away. 永远不会消失。 This is why your weak reference is never set to nil. 这就是为什么你的弱引用永远不会设置为nil。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM