2012-01-19 2 views
17

처음에는 CGPoint 속성을 특정 지점 (화면 중간)으로 설정하고 싶습니다. 이후에 다른 방법으로이 속성을 변경할 수 있습니다. 내 생각은 getter에서 비어있는 경우 초기화하는 것이었지만 unary 표현식에 잘못된 인수 유형 'struct CGPoint'가 표시됩니다. 나는 또한 property == nil 또는 0이지만 기쁨은 사용하지 않았다.CGPoint가 초기화되었는지 어떻게 확인합니까?

의견이 있으십니까?

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

}

답변

29

CGPoint을, 그래서 그것을 널이나 NULL로 설정할 수 없습니다 (포인터가 아닙니다). 어떤 의미에서는 실제로는 "초기화되지 않은"상태가 없습니다. 아마도 {0.0, 0.0}을 사용하여 설정되지 않은 CGPoint을 지정할 수 있지만 올바른 좌표이기도합니다. 또는 음수 값이 유효한 그리기 포인트가 아니기 때문에 xy 값을 사용하여 "초기화되지 않은"포인트를 표시 할 수 있지만 해킹 비트이기도합니다.

  1. 저장하시오 CGPoint에 대한 포인터로 특성 :

    은 아마 당신의 최선의 방법은 두 가지 중 하나를 수행하는 것입니다. 이 값은 초기화되지 않은 경우 NULL으로 설정할 수 있습니다. 물론, 당신은 malloc ing과 free 값에 대해 걱정해야합니다.

  2. 저장합니다 CGPointBOOL 함께 pointInitialized이라고 나 처음 NO로 설정하지만, 포인트가 초기화 된 후 YES로 설정, somesuch. 당신은 구조체에 그를 마무리 할 수 ​​

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

**이 답변은 ** {0.0, 0.0} **이 실제로 존재하고 유효한 좌표이기 때문에 훨씬 더 마음에 들었습니다. 이를 널 포인트로 사용하면 프로그램 논리가 손상 될 수 있습니다. – Stas

+1

CGPoint를 -1로 설정하면 -1은 다른 제안보다 나에게 덜 익숙해 보입니다. 별도의 부울 변수를 추가하는 것은 Single Point of Truth 위반처럼 보입니다. 변수 상태가 변경 될 때마다 업데이트되지 않으면 잘못된 결과가 나타납니다. – arlomedia

+0

아마도 끔찍한 프로그래밍이지만, 필사적이라면 {NAN, NAN}을 좌표로 CGPoint에 전달할 수 있습니다. – Tommyixi

10

CGPoint가 초기화되지 않은 상태가 없습니다. 이 점을 고려한다면, (0, 0) 초기화되지 않은, 당신은

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

오브젝티브 C 인스턴스가 초기화 될 때, 모든 바르가 제로의 비트를 클리어하고 있기 때문에이 작품에서 사용할 수 CGFloat 표현은 0.0입니다.

(참고 : 우리가 -0)의 문제를 무시합니다 (정확한 비트 패턴과 비교할 때문에 피연산자가 CGFloat을 경우에도 == 여기 괜찮습니다) 구조체입니다

+0

잘 작동, 감사합니다! – Alan

+9

(0, 0)은 유효한 좌표입니다 – jjeaton

+0

사실 @jjeaton – abbood

21

쉬운 방법은 CGRectZero를에 _graphOrigin를 초기화하고이에 대한 귀하의 if 문을 변경하는 것입니다 :

if (!CGPointEqualToPoint(_graphOrigin, CGPointZero)) { 

} 
0

두 CGPoint 속성을 작성, 그런 식으로 그들은 둘 다 "초기화되지 않은"것입니다. 그것들 중 하나를 설정하고 두번째 것을 사용하여 그들이 같은지 아닌지 확인하십시오.

@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 

만약 당신이 이런 식으로 hackish 생각. 그리고 당신의 질문이 이미 답변 된 것을 압니다. 그러나 이것에 대해서 생각할 때까지 나는 같은 딜레마를 가지고있었습니다.당신이 당신의 상황 에 존재할 수있는 포인트를 제공 CGPointZero (0,0) 및 다른 값 때문에

5

사용하여 포인트와 함께 NSValue를 초기화 할 수 있습니다 :

NSValue *pointVal = [NSValue valueWithCGPoint:point]; 

당신이 할 수있는이 기반 어떤 조건을 검사하고 나중에 NSValue를 테스트합니다. 배열에 NSValue를 추가하여 필요할 때 배열을 지정할 수 있습니다.

단순히 사용 나중에 포인트를 얻으려면 :

CGPoint point = [pointVal CGPointValue]; 
+0

이 솔루션은 'point'구조체가 있는지 IF 문을 확인하는 데 매우 유용합니다. pointVal이 nil (... if (pointVal) ...)인지 확인할 수 있습니다. point (... if (point) ...는 '잘못된 피연산자'오류를줍니다.)로 할 수 없습니다. – 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 
관련 문제