我正在努力理解ARC的工作方式,据我所知,我应该在这里做错了什么。这是我正在使用的代码:
接口:
@interface ViewController : UIViewController{
}
@property (strong, nonatomic) NSString * myString ;
@property (weak, nonatomic) NSString * myPointer ;
实施:
- (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) ;
}
执行此操作后,我得到:
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!
如果我没有错的话,由于myPointer很弱,它不应该保留对象的内容。因此,它应该显示nil而不是"Hello World!"。
我做错了什么?
根据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) ;
}
关键是,我仍然得到了以前的答案:
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!
正如Caleb所指出的,在这个例子中使用常量NSString不是一个好主意。
在源代码中创建字符串对象的最简单方法是使用Objective-C@"…"构造:
NSString*temp=@"/tmp/strack";请注意,在创建字符串时在这种方式下,您应该避免使用7位以外的任何东西ASCII字符。这样的对象在编译时创建并存在在程序执行的整个过程中。编译器生成这样的对象常数在每个模块的基础上是唯一的,并且它们永远不会被释放,尽管您可以像处理任何其他对象一样保留和释放它们。你也可以像执行任何操作一样直接向字符串常量发送消息其他字符串:
BOOL same=[@"comparison"isEqualToString:myString];
文档解释了常量字符串永远不会消失。
试着用其他东西做实验。我尝试了NSObject,它产生了预期的结果。
接口:
@interface ViewController : UIViewController
@property (strong, nonatomic) NSObject * myString;
@property (weak, nonatomic) NSObject * myPointer;
@end
实施:
@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
当没有指向内存的强指针时,弱指针将设置为零,如文档Apple Developer或llvm中所述。
__weak指定一个引用,该引用不会使被引用对象保持活动状态。当没有强引用时,弱引用设置为零对对象的引用。
因此,它应该显示nil而不是"Hello World!"。
常量字符串永远不会被释放,所以你的`@"Hello World!"永远不会消失。这就是为什么你的弱引用永远不会设置为零。