2012-01-19 43 views
17

Tôi muốn thiết lập thuộc tính CGPoint thành một điểm cụ thể (giữa màn hình). Các phương pháp khác sau đó có thể muốn thay đổi thuộc tính này. Suy nghĩ của tôi là khởi tạo nó nếu trống trong getter, nhưng tôi nhận được thông báo kiểu đối số không hợp lệ 'struct CGPoint' để biểu hiện đơn nhất. Tôi cũng đã cố gắng sử dụng nếu tài sản == nil hoặc 0 nhưng không có niềm vui.Làm cách nào để kiểm tra xem CGPoint đã được khởi tạo chưa?

Mọi suy nghĩ?

-(CGPoint)graphOrigin 
{ 
    // initialise to centre of screen if has not been set 
    if(!_graphOrigin) // this expression is causing the problem 
    { 
     CGPoint origin = CGPointMake(self.bounds.origin.x + self.bounds.size.width/2, self.bounds.origin.y + self.bounds.size.height/2); 

     _graphOrigin = origin; 
    } 

return _graphOrigin; 

}

Trả lời

29

Một CGPoint là một cấu trúc, vì vậy bạn không thể đặt nó thành nil hoặc NULL (nó không phải là một con trỏ). Trong một nghĩa nào đó, thực sự không có trạng thái "uninitialized". Có lẽ bạn có thể sử dụng {0.0, 0.0} để chỉ định một unset CGPoint, nhưng đó cũng là một tọa độ hợp lệ. Hoặc bạn có thể sử dụng các giá trị tiêu cực xy để gắn cờ điểm "chưa được khởi tạo" vì giá trị âm không thể là điểm vẽ hợp lệ, nhưng đó cũng là một chút của quá trình hack.

lẽ đặt cược tốt nhất của bạn là để làm một trong hai điều:

  1. Store sở hữu như một con trỏ đến một CGPoint. Giá trị này có thể được đặt thành NULL khi chưa được khởi tạo. Tất nhiên, bạn phải lo lắng về việc nhập giá trị malloc ing và free.
  2. Store CGPoint cùng một BOOL gọi pointInitialized hoặc somesuch, bước đầu thiết lập để NO, nhưng thiết lập để YES khi điểm đã được khởi tạo. Bạn thậm chí có thể bọc đó lên trong một cấu trúc:

    struct { 
        CGPoint point; 
        BOOL initialized; 
    } pointData; 
    
+3

Tôi thích câu trả lời này nhiều hơn, bởi vì ** {0.0, 0.0} ** là một tọa độ thực sự tồn tại và hợp lệ. Sử dụng nó như là một điểm rỗng có thể phá vỡ logic chương trình của bạn. – Stas

+1

Đặt CGPoint thành -1, -1 dường như ít gây hại cho tôi hơn các đề xuất khác. Việc thêm một biến boolean riêng biệt có vẻ giống như một điểm vi phạm Chân lý đơn lẻ - nó sẽ cho kết quả không chính xác nếu nó không được cập nhật bất cứ khi nào trạng thái của biến được thay đổi. – arlomedia

+0

Có lẽ lập trình kinh khủng, nhưng nếu bạn tuyệt vọng, bạn luôn có thể vượt qua {NAN, NAN} làm tọa độ với CGPoint của bạn. – Tommyixi

10

CGPoint không có một trạng thái chưa được khởi tạo. Tuy nhiên, nếu bạn xem xét các điểm (0, 0) là chưa được khởi tạo, bạn có thể sử dụng

if (_graphOrigin.x == 0 && _graphOrigin.y == 0) 
{ 
    ... 

này hoạt động bởi vì khi một thể hiện Objective-C được khởi tạo, tất cả Ivar nó bị giải tỏa để bit của số không, mà trong CGFloat đại diện là 0,0.

(Lưu ý: == là tốt ở đây thậm chí nếu các toán hạng là CGFloat bởi vì chúng tôi muốn so sánh với một mẫu bit chính xác (bỏ qua vấn đề -0))

+0

hoạt động tốt, cảm ơn! – Alan

+9

(0, 0) là toạ độ hợp lệ – jjeaton

+0

đúng là @jjeaton – abbood

21

Một cách dễ dàng hơn sẽ được khởi tạo _graphOrigin để CGRectZero và thay đổi nếu tuyên bố của bạn cho việc này:

if (!CGPointEqualToPoint(_graphOrigin, CGPointZero)) { 

} 
0

Tạo hai thuộc tính CGPoint, theo cách đó, cả hai đều "chưa được khởi tạo". Đặt một trong số chúng và sử dụng thứ hai để kiểm tra xem chúng có bằng nhau hay không.

@interface ClassName() 

@property (nonatomic) CGPoint point1; 
@property (nonatomic) CGPoint point2; 

@end 

@implementation ClassName 

self.point1 = CGPointMake(69.0f, 180.0f); //arbitrary numbers 

    //if not equal, then if statement proceeds 
if (!CGPointEqualToPoint(self.point1, self.point2) { 
    //your code here 
} 

@end 

Giả sử nếu bạn cân nhắc theo cách này thì sẽ bị hack. Và tôi biết câu hỏi của bạn đã được trả lời, nhưng tôi đã có cùng một tình huống khó xử cho đến khi tôi nghĩ về điều này.

5

Kể từ CGPointZero (0,0) và bất kỳ giá trị khác mà bạn cung cấp cho một điểm có thể tồn tại trong bối cảnh của bạn bạn có thể muốn khởi tạo một NSValue với quan điểm của bạn sử dụng:

NSValue *pointVal = [NSValue valueWithCGPoint:point]; 

Bạn có thể làm điều này dựa trên một số điều kiện và sau đó kiểm tra NSValue cho nil. NSValue cũng có thể được thêm vào một mảng cho phép bạn có một mảng điểm bạn cần.

Để có được điểm sau đó chỉ cần sử dụng:

CGPoint point = [pointVal CGPointValue]; 
+0

Giải pháp này rất hữu ích cho một câu lệnh IF kiểm tra nếu cấu trúc 'điểm' tồn tại. Bạn có thể kiểm tra nếu pointVal là nil (... if (pointVal) ...), mà bạn không thể làm với điểm (... if (point) ... cung cấp cho bạn một lỗi 'toán hạng không hợp lệ'). – GlennRay

0
static CGPoint kInvalidPoint = {.x = NSIntegerMax, .y = NSIntegerMax}; 

@implementation MyClass 

- init() 
{ 
    self = [super init]; 
    if (self) { 
     _oldPoint = kInvalidPoint; 
    } 
    return self; 
} 

- (void)foo 
{ 
    if (CGPointEqualToPoint(self.oldPoint, kInvalidPoint)) { 
     // Invalid point. 
     return; 
    } 
} 

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