2012-06-28 27 views
5

là gì về mặt kỹ thuật xảy ra với những điều sau đây:Objective-C bất động sản - getter hành vi

@property(nonatomic, assign) NSUInteger timestamp; 
@property(nonatomic, readonly, getter = timestamp) NSUInteger startTime; 
@property(nonatomic, assign) NSUInteger endTime; 

Tôi chắc chắn tôi có thể tìm thấy một cách tốt hơn để tổ chức này, nhưng đây là những gì tôi đã kết thúc với cùng một điểm trong dự án của tôi và tôi nhận thấy rằng truy cập thuộc tính startTime luôn trả về 0, ngay cả khi thuộc tính dấu thời gian được đặt thành dấu thời gian chính xác.

Dường như đã thiết lập các getter của StartTime để một tài sản (timestamp) đang tồn tại, nó không được chuyển tiếp giá trị của dấu thời gian khi tôi làm:

event.startTime => 0 
event.timestamp => 1340920893 

Tất cả những là timestamps bằng cách này.

Chỉ cần một lời nhắc, tôi biết điều trên đã xảy ra trong dự án của tôi nhưng tôi không hiểu tại sao việc truy cập startTime không chuyển tiếp lên thuộc tính dấu thời gian.

CẬP NHẬT

Thực hiện tôi đang synthesising tất cả các thuộc tính:

@synthesize timestamp, endTime, startTime; 

Vui lòng kiểm tra một đối tượng ví dụ để sử dụng thể hiện này tại ý chính của tôi trên GitHub: https://gist.github.com/3013951

+0

Lỗi là gì? Với 'getter'? –

+0

Thực ra, câu trả lời của tôi là sai. Việc bạn có nhiều thuộc tính được liên kết với cùng một bộ chọn không quan trọng. Tôi muốn nói rằng không có vấn đề với điều này ... –

+0

@ RichardJ.RossIII Tôi chỉ chạy thử nghiệm của tôi trong XCode mới nhất trong một dự án ARC. Có thể đây là một sự thay đổi ở Clang tại một thời điểm nào đó. – Joe

Trả lời

5

Trong phương pháp mô tả, bạn không sử dụng thuộc tính, bạn đang truy cập ivar.

-(NSString*) description 
{ 
    return [NSString stringWithFormat:@"Event< timestamp:%d, start:%d >", 
      timestamp, 
      startTime]; // <-- This is accessing the instance variable, not the property. 
} 

này sẽ làm việc cho bạn:

-(NSString*) description 
{ 
    return [NSString stringWithFormat:@"Event< timestamp:%d, start:%d >", 
      timestamp, 
      self.startTime]; // <-- This is using the property accessor. 
} 

Điều bất động sản-vs-Ivar messes người lên tất cả các thời gian, vì vậy cho tôi xin lỗi khi tôi huyên thuyên về nó trong một phút. :) Nếu bạn đã biết tất cả điều này, hãy bỏ qua.

Khi bạn tạo và tổng hợp một tài sản, như bạn đã làm ở trên, có hai điều xảy ra:

  1. một Ivar được tạo ra loại thích hợp.
  2. một hàm getter được tạo ra, trả về ivar đó.

Phần quan trọng về điểm 2 là, theo mặc định, Ivar và hàm getter (và do đó, tài sản) có cùng tên.

Vì vậy, đây:

@interface Event 
@property(nonatomic, assign) NSUInteger timestamp; 
@property(nonatomic, readonly, getter = timestamp) NSUInteger startTime; 
@end 

@implementation Event 
@synthesize timestamp, startTime; 
@end 

...biến thành này:

@interface Event { 
    NSUInteger timestamp; 
    NSUInteger startTime; 
} 
@end 

@implementation Event 
- (NSUInteger) timestamp { 
    return timestamp 
} 

- (void) setTimestamp:(NSUInteger) ts { 
    timestamp = ts; 
} 

- (NSUInteger) startTime { 
    return [self timestamp]; 
} 
@end 

Làm thế nào chấm cú pháp làm việc là điều này:

NSUInteger foo = myEvent.startTime; 

thực sự

NSUInteger foo = [myEvent startTime]; 

Tất cả điều đó để nói rằng khi bạn truy cập vào một Ivar, bạn ... tốt, truy cập một cái ngà. Khi bạn sử dụng một thuộc tính, bạn đang gọi một hàm trả về một giá trị. Quan trọng hơn, nó cực kỳ dễ dàng để làm một điều khi bạn có nghĩa là khác, bởi vì cú pháp rất giống nhau. Đó là vì lý do này mà nhiều người thường xuyên tổng hợp ivars của họ với dấu gạch dưới hàng đầu, để nó khó khăn hơn để mess up.

@property(nonatomic, assign) NSUInteger timestamp; 
@property(nonatomic, readonly, getter = timestamp) NSUInteger startTime; 

@synthesize timestamp = _timestamp; 
@synthesize startTime = _startTime; 

NSLog(@"startTime = %d", _startTime); // OK, accessing the ivar. 
NSLog(@"startTime = %d", self.startTime); // OK, using the property. 
NSLog(@"startTime = %d", startTime); // NO, that'll cause a compile error, and 
             // you'll say "whoops", and then change it 
             // to one of the above, thereby avoiding 
             // potentially hours of head-scratching. :) 
+0

Tất nhiên. tại chỗ trên. Nó rất đơn giản nó phức tạp! Đôi khi bạn đang nhìn qua bề mặt và quá sâu vào một cái gì đó. Một lần nữa một câu hỏi ngớ ngẩn của bản thân mình ... Cảm ơn bạn đã trả lời. Thú vị để lưu ý rằng tôi thường sử dụng thực hiện gạch dưới nhưng đối với một số lý do lớp này của tôi đã rất đơn giản và tôi quyết định giữ nó với mã ít hơn. Bài học trong ngày: Giữ phong cách mã hóa của bạn. Oh và không đặt câu hỏi trên Stack Overflow mà không thực sự điên rồ trước – Daniel

1

Hãy chắc chắn rằng bạn tổng hợp theo thứ tự đúng để getter tồn tại cho startTime.

//implementation 
@synthesize timestamp; 
@synthesize statTime; 
+0

Tôi đã không chú ý đặc biệt đến thứ tự của điều này nhưng nó quay ra tôi đang làm điều đó. Trừ khi tôi cần phải cụ thể thiết lập tổng hợp trên một dòng mới. Tôi đang làm @synthesize p1, p2, p3; Có lẽ điều này không phải là không ưu tiên các thuộc tính? – Daniel

+0

Bạn đang sử dụng trình biên dịch nào? Tôi đang sử dụng Apple LLVM 3.1 và nó làm việc tốt cho tôi. – Joe

+0

Tôi đang sử dụng tương tự. Tôi chỉ đăng một liên kết đến một mã mẫu, hãy kiểm tra nó trên mặt của bạn nếu bạn sẽ rất tử tế. – Daniel

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