development

Objective-C의 속성 및 인스턴스 변수

big-blog 2021. 1. 8. 22:47
반응형

Objective-C의 속성 및 인스턴스 변수


Objective-C의 속성과 인스턴스 변수에 대해 다소 혼란 스럽습니다.

저는 Aaron Hillegass의 "Mac OS X 용 Cocoa 프로그래밍"을 반쯤 진행 중이며 모든 것이 논리적입니다. 다음과 같은 클래스를 선언합니다.

@class Something;

@interface MyClass : NSObject {
    NSString *name;
    NSArray *items;

    Something *something;

    IBOutlet NSTextField *myTextField;
}

@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSArray *items;
  • 다른 객체는 우리 nameitems인스턴스 변수 를 조작해야하기 때문에 @property/ @synthesize사용 하여 접근 자 / 변이 자를 생성합니다. 클래스 내에서 접근 자 / 뮤 테이터를 사용하지 않고 인스턴스 변수와 직접 상호 작용합니다.

  • something 클래스에서 사용할 인스턴스 변수 일 뿐이며 다른 사람이 사용할 필요가 없기 때문에 접근 자와 뮤 테이터 쌍을 만들지 않습니다.

  • UI의 텍스트 필드와 상호 작용해야하므로 IBOutletfor it 을 선언하고 연결하면 완료됩니다.

모두 매우 논리적입니다.

그러나 iPhone 세계에서는 상황이 달라 보입니다. 사람들은 모든 단일 인스턴스 변수에 대한 속성을 선언하고,에 대한 속성을 선언하고 IBOutlets, 접근 자 / 뮤 테이터를 사용 하여 클래스 내의 인스턴스 변수와 상호 작용 합니다 (예 : [self setName:@"Test"]보다는 쓰기 name = @"Test").

왜? 무슨 일이야? 이러한 차이점은 iPhone에만 해당됩니까? 모든 인스턴스 변수에 대한 속성을 선언하고에 대한 속성을 선언 IBOutlets하고 자신의 클래스 내에서 접근 자 / 뮤 테이터를 사용 하면 어떤 이점이 있습니까?


iPhone 세계에는 가비지 수집기가 없습니다. 참조 카운팅으로 메모리를 신중하게 관리해야합니다. 이를 염두에두고 다음의 차이점을 고려하십시오.

name = @"Test";

self.name = @"Test";
// which is equivalent to:
[self setName: @"Test"];

사전 고려없이 인스턴스 변수를 직접 설정하면 이전 값에 대한 참조를 잃게되고 보유 횟수를 조정할 수 없습니다 ( release수동으로 설정해야 함). 속성을 통해 액세스하면 새로 할당 된 개체의 보유 개수가 증가하는 것과 함께 자동으로 처리됩니다.

기본 개념은 iPhone에만 국한되지 않지만 가비지 수집기가없는 환경에서는 중요합니다.


속성은 인스턴스 변수에 대한 접근자를 생성하는 데 사용되며 마술은 일어나지 않습니다.

동일한 접근자를 직접 구현할 수 있습니다.

Aaron Hillegass의 책에서 멤버 변수에 대한 3 가지 메모리 관리 전략의 예를 찾을 수 있습니다. 그들은입니다 assign/copy/retain. 주어진 변수에 필요한 것 중 하나를 선택합니다.

Objective-c의 메모리 관리를 이해한다고 가정합니다.

접근자는 각 변수에 대한 메모리 관리의 복잡성과 차이점을 숨 깁니다.

예를 들면 :

name = @"Test"

은 간단한 할당이며 name이제 NSString @"Test". 그러나 copy또는 을 사용할 수 있습니다 retain. 선택한 메모리 관리 버전에 관계없이 접근자는 복잡성을 숨기고 항상 다음을 사용하여 변수에 액세스합니다.

[self setName:@"Test"] 
[self name]

이제 setName:사용할 수 assign/copy or retain있으며 걱정할 필요가 없습니다.

My guess is that iPhone tutorials use properties to make it easier for new developers to jump through memory management (even though it's handy to generate appropriate accessors with properties rather than implement them by hand every time).


However, in the iPhone world, things seem to be different. People declare properties for every single instance variable, declare properties for IBOutlets, and use accessors/mutators to interact with instance variables within the class (e.g. they would write [self setName:@"Test"] rather than name = @"Test").

That's not iPhone-specific. Except in init methods and the dealloc method, it's good practice to always use your accessors. The main benefit, especially on the Mac (with Cocoa Bindings), is that using your accessors means free KVO notifications.

The reason why people “declare properties for every single instance variable” is most probably that all of their instance variables are things they want to expose as properties. If they had something they would want to keep private, they would not declare a property for it in the header file. (However, they may make a property for it in a class extension in the implementation file, in order to get the aforementioned free KVO notifications.)

Declaring properties for outlets is overkill, in my opinion. I don't see a point to it. If you don't make a property, the nib loader will set the outlet by direct instance-variable access, which is just fine for that task.


I would suggest that modern development has made a very strong attempt to identify, define and apply best practices.

Among these best practices we find continuity and consistency.

Apart from arguing over use of accessors in init and dealloc methods, accessors should generally be used all the time (inside and outside of a class) for the benefits they offer, including encapsulation, polymorphic var implementations (which both allow for abstracting and refactoring) and to facilitate those best practices of continuity and consistency. The fundamental benefits of an object-orient language come into play when doing things in this way and exploiting the fullness of the language's capabilities. Always being consistent in one's coding is an oft undermentioned benefit, as any senior programmer will usually attest.


You can write like this

//MyClass.h

@class Something;

@interface MyClass : NSObject 

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSArray *items;

@end 

//MyClass.m
@interface MyClass() 

@property (nonatomic, strong) IBOutlet NSTextField *myTextField;
@property (nonatomic, strong) Something *something;

@end

ReferenceURL : https://stackoverflow.com/questions/1551966/properties-and-instance-variables-in-objective-c

반응형