2012-02-26 53 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