2014-11-11 4 views
2

가 나는 UIView 속성과 서브 클래스가는 속성 setter의 행동에 의해 혼란

(이 질문은 아마 더 자세한 설명 제목을 필요로 그것을 개선 주시기 바랍니다) 나는 가지고있는 방법 :

[self addSubview: (self.label = [UILabel new])]; 

나는 그것의 간명을 좋아한다, 그러나 나는 그것이 어떻게 작동하는지 질문을 받는다.

Assigning retained object to weak property; object will be released after assignment 

옆 경고, 실제로 작동하는 것 같다 :

하나, 나는 경고를 얻을. 그것은 릴리스 기계가 실행되기 전에 addSubview:이 그것을 다시 보유하기 때문입니까?

정확하게 이해하면 코드는 [self setLabel: ...]의 설탕 일뿐입니다. 난 내 자신의 setLabel: 구현 속성 액세스를 무시한다면, 그 서명은

- (void) setLabel: (UILabel*) label; 

그래서 반환 값이 무효입니다 될 것입니다. 그러나 그것은 보내고 작동하는 addSubview:에 먹이를주고 있습니까? 어떻게 작동합니까? 여기에 하나 라이너를하고 좌절하는 일의

업데이트

하나는 Objective-C는 처음에 목표 - C를 양산 Smalltalk 영향에서 분기되는 addSubview: 같은 방법에서 유용한 정보를 반환 피하다하는 경향이 있다는 것입니다 . Smalltalk에서는 추가 된 객체를 반환하는 것이 보통/addSubview: 메서드에서 예상됩니다.

self.label = [self addSubview: [UILabel new]]; 

이 강한/약한 의미는 행복 할 수 있도록합니다 : 이런 경우라면, 하나는 이러한 식을 작성할 수 있습니다. addSubview:은 약한 사람 label setter에 도착하기 전에 강력한 유지를합니다.

내가 subviewsrecognizers 모두이 문제를 싸움, 그래서 내가 영리하고, 그런 일을 할 수있는 category 쓰기 거라고 생각 (나는 다른 addSubview 쉽게 구별 될 수 있도록 수신기/인수를 반전 : 서명).

@interface UIView (UIView_Adding) 
    - (UIView*) addedToView: (UIView*) superview; 
@end 

@interface UIGestureRecognizer (UIView_Adding) 
    - (UIGestureRecognizer*) addedToView: (UIView*) view; 
@end 

@implementation UIView (UIView_Adding) 
- (UIView*) addedToView: (UIView*) superview { 
    [superview addSubview: self]; 
    return self; 
} 
@end 

@implementation UIGestureRecognizer (UIView_Adding) 
- (UIGestureRecognizer*) addedToView: (UIView*) view { 
    [view addGestureRecognizer: self]; 
    return self; 
} 
@end 

불행히도, 이것은 불행히도, 추악한 법칙을 불러옵니다. 나는 한 종류의 경고를 없애고 다른 경고를 얻는다.

self.label = [[UILabel new] addedToView: self]; 

을하지만이 self.labelUIView의 특정 서브 클래스, 즉 UILabeladdedToView:의 반환 형식은`UIView의 '를 개최하기위한 것입니다 있다는 경고가 발생하는 경우를 포함하여 해당 범주로, 지금 쓸 수 있습니다. Objective-C 의사 유형을 알지 못합니다. 즉, 은이 알려진 수퍼 유형의 오른쪽 놈 (subtype)이되어 속성 유형을 행복하게 만듭니다..최종 업데이트

:(

은 내가 instancetype 유형을 발견했다. 이러한 형태를 돌려 내 카테고리 메소드 서명을 변경하여, 모든 것이 작동합니다. 내가 여기서 뭔가를 학대하고있어 알고하지 않을 정도로 instancetype에 새로운 해요 하지만 나는 그것이 작동 오싹

답변

2

경고는에서 온다 :.. 당신의 label 속성이 weak 때문에

self.label = [UILabel new] 

addSubview:에 대한 호출로 레이블이 유지되므로 제대로 작동하는 것이 맞습니다.

하지만 수퍼 뷰에서 레이블을 제거하면 label 속성이 nil이되어 레이블이 손실됩니다. 따라서 레이블이 제거 될 가능성이 있지만 레이블에 대한 참조를 유지하려는 경우 (나중에 다시 추가 할 수 있음) 속성을 strong으로 변경하십시오.

또한 self.label =이 실제로 단지 [self setLabel:]임을 수정했습니다. 이 값을 addSubview:으로 전달할 수있는 이유는 x = y과 같은 식의 값이 할당과 같기 때문입니다. 그래서

:

[self addSubview: (self.label = [UILabel new])]; 

에 해당하는 경우 :

UIView *view = (self.label = [UILabel new]); 
[self addSubview:view]; 
+0

이 유지되지 않습니다 시간도있다 : 두 개의 문 사이가. 이 구성은 신뢰할 수 없습니다. 그러나 일반적으로 하위보기는 부모보기에서만 유지되므로 대개 약한 것으로 선언되는 것이 일반적입니다. – zaph

+0

@Zaph 내 대답의 마지막 두 줄에 대해서 이야기하고 있다고 가정하면 로컬 변수'view'가'strong'이므로 의존 할 수 있습니다. – rmaddy

+0

이 속성은 실제로 자동 실행되지 않으며 실행 루프가 현재주기를 마친 후에 만 ​​사라집니다. – ahwulf