2013-04-15 1 views
1
@interface RandomObject : NSObject 
{ 
    NSString* someObject; // I know I don't have to explicitly declare. Just to clarify my point. 
} 
@property (nonatomic, strong) NSString *someObject; 
@end 

@implementation RandomObject 
@synthesize someObject; 
@end 

위의 코드와 Xcode 4.3이 사용되었으므로 (따라서 자동 합성 없음) 여기에 내 질문이 있습니다.목표 C : 차별화 된 iVars 및 접근 자

속성/synthesize는 someObject, 즉 getter 및 setter에 대한 접근자를 만듭니다. 따라서 someObject에 값을 할당하려면이 작업을 수행 할 수 있습니다.

내 이해가 정확하다면, 자기는 @ "토마토"를 setSomeObject 메소드에 보냅니다. 그러나 만약 당신이 이것을한다면?

someObject = @"Tomato"; // or maybe _someObject = @"Tomato" if you are doing auto-synthesizing 

직접 바르 개체에 액세스하는 나쁜 생각처럼 보이지만, someObject라는부터 개인 변수는 바로, 당신이에 대한 액세스 권한이 같은 클래스 내에서인가?

다른 클래스의 someObject를 조작하려면 self.someOject를 사용해야하는 이유를 알고 있습니다. 그러나 같은 학급에 아직도 있더라도 같은 것을해야 할 필요가있는 이유는 무엇입니까? iVar에 직접 액세스하는 것이 좋지 않은 이유는 무엇입니까?

+1

나는 항상'someObject = @ "Tomato"대신에'self.someObject = @ "Tomato"를 사용하고 모든 것이 완벽하게 작동한다. 결코 오류가 발생하지 않는다. – Moray

+0

내 지식으로는 이것들은 거의 같다. 'self.someObject'는 당신이 작업하고있는 객체의 ivar 값입니다. 'someObject'는 로컬에서 선언 된 변수입니다.이 경우 헤더 파일에 선언 된 ivar입니다. 그래서'self.someObject'를 사용하면'self'의 ivars를보고'someObject'라고 부르는 ivar를 찾을 것입니다. 반면에'someObject'는 ivar로 선언 되었기 때문에 직접 ivar에 값을 할당 할 것입니다. 내가 틀렸다고 말해줘. – Moray

+1

가능한 복제본 [iOS : 모든 iVar이 실제로 소유해야합니까?] (http://stackoverflow.com/questions/5031230/ios-must-every-ivar-really-be-property) – Monolo

답변

2

이 속성은 개체를 ivar에 할당하는 것 이상의 역할을합니다.

ARC를 사용하지 않으면 속성은 메모리 관리를 처리하기 위해 보유/릴리스 코드를 자동으로 생성합니다. someObject = @"Tomato"을 호출하면 메모리 누수가 발생합니다 (someObject가 할당 된 경우)

속성이 atomic 인 경우이 속성은 스레드 안전성을 제공하지만 ivar는 스레드로부터 안전하지 않습니다.

자동 생성 속성 코드의 예는 https://stackoverflow.com/a/589348/1597531을 참조하십시오.

3

일반적으로 말하면 접근자는 접근 할 수있는 것보다 더 많은 장점이 있으며 가능한 모든 곳에서 사용합니다.

중요한 문제는 직접적으로 ivar를 참조하는 모든 장소가 코드를 변경해야하는 또 다른 잠재적 장소라는 것입니다.

예를 들어 반 전체에 걸쳐 여러 곳에서 someObject을 참조했다고 상상해보십시오. 그런 다음 요구 사항이 변경되어 이제 someObject 값이 할당되면 다른 작업이 필요하다는 결론을 얻었습니다. 클래스 전반에 걸쳐 직접 ivar에 액세스 했으므로 someObject 또는 리팩터링을 할당하는 모든 곳에서이 새 코드를 복제해야합니다. 당신이 접근을 사용하는 경우 당신은 그냥

- (void)setSomeObject:(id)anObject 
{ 
    if (anObject != someObject) { 
    someObject = anObject; 
    [self doSomeWork]; 
    } 
} 

당신은 게터와 같은 문제가있을 수 있습니다 변경하는 코드의 한 조각을 가지고 - 당신이 someObjects에서 객체의 배열을 저장 상상 - 이것은 아래 다음 나중에 잘 작동하지만, 다른 값에서 동적으로 계산할 수 있으므로 실제로 someObjects을 저장할 필요가 없다고 결정했습니다. 어디서나 직접 ivar에 액세스했다면 큰 일이됩니다. 당신이 다음 게터 뒤에 someObject을 추상화에 충실하면 당신이 지금해야 할 일은 (이것은 한 곳에서 바르의 메모리 관리를두고 비 ARC 코드와 정확히 생각이다

- (NSArray *)someObjects 
{ 
    return [self calculateSomeObjects]; 
} 

입니다 코드 뒤에 반복적 인 코드를 사용하지 않아도됩니다.