2012-02-26 52 views
5

我想了解ARC的工作方式,而据我所知,应该是我错在这里做一些事情。这是我使用的代码:的iOS 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是软弱,它不应该保留对象的内容。所以,它应该显示为零,而不是“世界,你好!”。

我在做什么错?

继迦勒的答案,我创造了另一种弱指针,请参见下面的代码:

- (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! 

回答

8

正如迦勒指出的那样,使用这个例子恒定的NSString是不是一个好主意。

来创建源代码的字符串对象中的最简单的方法是使用目标C @ “...” 构建体:

的NSString *温度= @ “/ TMP /从零开始”;需要注意的是,创造了这种方式的字符串常量 时,应避免使用任何东西,但7位 ASCII字符。这样的对象是在编译时创建和存在 整个程序的执行。编译器在每个模块基础上使这些对象的常量是唯一的,并且它们永远不会被释放,尽管您可以像其他对象一样保留和释放这些常量。您 也可以直接发送消息给一个字符串常量,你做任何 其他字符串:

BOOL相同= [@“比较” isEqualToString:myString的]。

documentation解释了常量字符串永远不会消失。

尝试使用别的方法进行实验。我试过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 

弱指针设置为nil - Apple Developerllvm

__weak指定了不保存引用的对象活着的参考。当没有强对象的引用时,弱引用设置为零。

+0

明智的答案,非常感谢。 – RGML 2012-02-26 12:40:34

5

所以,它应该显示为零,而不是“世界,你好!”。

常量字符串永远不会被释放,所以你的`@“Hello World!”永远不会消失。这就是为什么你的弱引用从来没有设置为零。

+0

感谢您的回答迦勒。这是有道理的,但是,我已经创建了另一个弱指针来测试你说的话。不幸的是,你可以看到,它不起作用。 – RGML 2012-02-26 12:07:02

+0

@Arkyxperience你期待什么发生? – Caleb 2012-02-26 14:22:25

+5

弱引用被设置为零,当他们的目标被释放时。这是ARC的一个特点 - 合成的弱特性决不会持有悬挂指针。 – FellowMD 2012-06-30 17:35:45