2012-02-26 27 views
5

Tôi đang cố gắng hiểu cách ARC hoạt động, và theo như tôi biết, tôi nên làm điều gì sai ở đây. Đây là mã Tôi đang sử dụng:iOS ARC - thuộc tính yếu và mạnh

Interface:

@interface ViewController : UIViewController{ 

} 

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

Thực hiện:

- (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) ; 
} 

Sau khi thực hiện điều này, tôi nhận được:

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! 

Nếu Tôi không sai, do myPointer là yếu, nó không nên giữ lại nội dung của đối tượng. Vì vậy, nó sẽ hiển thị nil thay vì "Hello World!".

Tôi đang làm gì sai?

Sau câu trả lời Caleb, tôi đã tạo ra một con trỏ yếu, xem mã bên dưới:

- (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) ; 
} 

Vấn đề là tôi vẫn có câu trả lời giống như tôi đã từng có:

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! 

Trả lời

8

Như Caleb đã chỉ ra, việc sử dụng NSString không đổi cho ví dụ này không phải là một ý tưởng hay.

Cách đơn giản nhất để tạo ra một đối tượng chuỗi trong mã nguồn là sử dụng Objective-C @ "..." xây dựng:

NSString * temp = @ "/ tmp/đầu"; Lưu ý rằng, khi tạo một chuỗi không đổi theo kiểu này, bạn nên tránh sử dụng bất kỳ thứ gì trừ 7-bit ký tự ASCII. Đối tượng như vậy được tạo tại thời gian biên dịch và tồn tại trong suốt quá trình thực thi chương trình của bạn. Trình biên dịch tạo các đối tượng như vậy hằng số duy nhất trên cơ sở mỗi mô-đun và chúng không bao giờ được phân phối lại, mặc dù bạn có thể giữ lại và giải phóng chúng khi bạn thực hiện bất kỳ đối tượng nào khác. Bạn cũng có thể gửi tin nhắn trực tiếp đến chuỗi không đổi như bạn thực hiện bất kỳ chuỗi khác:

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

documentation giải thích rằng chuỗi không đổi sẽ không bao giờ biến mất.

Hãy thử sử dụng thứ gì đó khác cho thử nghiệm của bạn. Tôi đã thử NSObject và nó tạo ra kết quả mong đợi.

Interface:

@interface ViewController : UIViewController 

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

@end 

Thực hiện:

@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 

con trỏ Yếu được thiết lập để nil khi không có con trỏ mạnh vào bộ nhớ như được giải thích trong tài liệu - Apple Developer hoặc llvm.

__weak chỉ định tham chiếu không giữ đối tượng được tham chiếu còn hoạt động. Tham chiếu yếu được đặt thành 0 khi không có tham chiếu mạnh mẽ cho đối tượng.

+0

Câu trả lời sáng chói, cảm ơn rất nhiều. – RGML

5

Vì vậy, nó sẽ hiển thị nil thay vì "Hello World!".

Chuỗi không đổi sẽ không bao giờ được phân phối, do đó, `@" Hello World! " không bao giờ biến mất. Đây là lý do tại sao tham chiếu yếu của bạn không bao giờ được đặt thành 0.

+0

Cảm ơn câu trả lời của bạn Caleb. Điều đó có ý nghĩa, tuy nhiên, tôi đã tạo ra một con trỏ yếu khác để kiểm tra những gì bạn nói. Thật không may, như bạn thấy, Nó không hoạt động. – RGML

+0

@Arkyxperience Bạn đang mong đợi điều gì sẽ xảy ra? – Caleb

+5

Tham chiếu yếu được đặt thành 0 khi mục tiêu của chúng được phân bổ. Đây là một tính năng của các thuộc tính yếu được tổng hợp ARC sẽ không bao giờ giữ một con trỏ lơ lửng. – FellowMD

Các vấn đề liên quan