Objective-C의 약하고 강력한 속성 setter 속성


94

Objective-C에서 약한 속성 설정자와 강력한 속성 설정 기 속성의 차이점은 무엇입니까?

@property(retain, [weak/strong]) __attribute__((NSObject)) CFDictionaryRef myDictionary;

영향과 이점은 무엇입니까?

iOS 4에서는 약한 기능을 사용할 수 없다고 들었는데 할당을 사용해야합니다.

약한 할당과 비슷합니까?


답변:


102

특정 파일에 대해 ARC를 켜거나 끕니다. 켜져 있으면 retain release autorelease등을 사용할 수 없습니다 . 대신 strong weak속성 또는 __strong __weak 변수에 사용 합니다 (기본값은 __strong). Strong은 유지하는 것과 동일하지만 ARC가 릴리스를 관리합니다.

weak를 사용하고 싶은 유일한 경우는 유지주기를 피하려는 경우입니다 (예 : 부모가 자식을 유지하고 자식이 부모를 유지하므로 둘 다 릴리스되지 않음).

'toll free bridging'부분 (에서 NS로 캐스팅 CF)은 약간 까다 롭습니다. 당신은 수동으로 관리해야 CFRelease()하고 CFRetain()CF 개체를합니다. 그것들을 다시 NS 객체로 변환 할 때 컴파일러에게 당신이 무엇을했는지 알 수 있도록 리 테인 카운트에 대해 알려야합니다.

모두 여기에 있습니다 .


119

다음은 변수 속성에 대해 알고있는 정보입니다.

  1. 원자 // 기본값
  2. 비 원자
  3. strong = 보유 // 기본값
  4. 약한
  5. 유지
  6. // default 할당
  7. unsafe_unretained
  8. 읽기 전용
  9. 읽기 / 쓰기 // 기본값

아래는 위에서 언급 한 모든 속성을 찾을 수있는 자세한 기사 링크입니다. 최고의 답변을 주신 모든 분들께 감사드립니다 !!

iOS의 변수 속성 속성 또는 수정 자

01. 강함 (iOS4 = 유지) - "더 이상 가리 키지 않을 때까지 힙에 보관"이라고 표시됩니다. 다시 말해서 "나는 소유자입니다. 조준하기 전에 할당을 해제 할 수 없습니다. "-개체를 유지해야하는 경우에만 strong을 사용합니다. -기본적으로 모든 인스턴스 변수와 지역 변수는 강력한 포인터입니다. -우리는 일반적으로 UIViewControllers (UI 항목의 부모)에 대해 strong을 사용합니다.-strong은 ARC와 함께 사용되며 기본적으로 오브젝트의 보유 수에 대해 걱정할 필요가 없으므로 도움이됩니다. ARC는 작업이 끝나면 자동으로 해제합니다. strong 키워드를 사용하면 해당 개체를 소유하고 있음을 의미합니다.

예:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

02. weak (iOS4 = unsafe_unretained) - "다른 사람이 강력하게 가리키는 한 유지"라고 표시됩니다.-할당, 유지 또는 해제와 동일합니다.- "약한"참조는 유지하지 않는 참조입니다. -우리는 일반적으로 IBOutlets (UIViewController의 Childs)에 약한 것을 사용합니다. 이것은 자식 개체가 부모 개체가있는 한만 존재하면되기 때문에 작동합니다. -약한 참조는 참조 된 개체를 가비지 수집기의 수집으로부터 보호하지 않는 참조입니다. -약함은 본질적으로 유지되지 않는 재산입니다. 객체가 할당 해제되는 경우를 제외하고 약한 포인터는 자동으로 nil로 설정됩니다.

예 :

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@synthesize myButton;

설명 : BJ Homer 덕분에

우리의 물체가 개이고 그 개가 도망 치고 싶어한다고 상상해보십시오 (할당 해제 됨). 강력한 포인터는 강아지의 끈과 같습니다. 개에 가죽 끈을 달고있는 한 개는 도망 가지 않습니다. 5 명이 한 마리의 개에게 가죽 끈을 붙이면 (하나의 물체에 5 개의 강한 포인터), 다섯 마리의 가죽 끈이 모두 분리 될 때까지 개는 도망 가지 않습니다. 반면에 약한 포인터는 어린 아이가 개를 가리키며 "봐! 개!"라고 말하는 것과 같습니다. 개가 여전히 목줄에있는 한 어린 아이들은 여전히 ​​개를 볼 수 있으며 여전히 개를 가리킬 것입니다. 그러나 모든 목줄이 분리 되 자마자 얼마나 많은 어린 아이들이 그것을 가리키고 있더라도 개는 도망칩니다. 마지막 강력한 포인터 (끈)가 더 이상 개체를 가리 키지 않으면 개체가 할당 해제되고 모든 약한 포인터가 0이됩니다. 약한 것을 사용할 때? weak를 사용하고 싶은 유일한 경우는 유지주기를 피하려는 경우입니다 (예 : 부모가 자식을 유지하고 자식이 부모를 유지하므로 둘 다 릴리스되지 않음).


1
초기 목록에서 "기본값"이 무엇을 의미하는지 잘 모르겠습니다. 둘 다 strong=retain있고 assign기본값으로 레이블이 지정되어 있지만 둘 다일 수는 없습니다.
Slipp D. Thompson 2013

27
가죽 끈 비교에서 개를 즐겼습니다. 꽤 잘 설명합니다.
Jarrett Barnett

1
iOS는 가비지 수집을 사용하지 않지만 좋은 설명입니다. ARC! = Garbage collection (!), 이들은 다른 기술입니다.

1
weak 및 unsafe_unretained는 다릅니다 (첫 번째는 약한 참조를 0으로 사용하고 후자는 스쿼트를
사용함

1
난 단지 아이폰 OS를 배우고,하지만 당신은을 잘못 한 것 같다 weak그리고 strong당신의 예에. 그것은 부모가 가지고있는 더 의미하지 않을까요 strong합니다 (같은 자식에 대한 참조 myButton의 재산 UIViewController이 될 보여준 클래스 weak) 아이들 유지하는 weak등 (부모에 대한 참조를 viewController자식 클래스의 호텔 인 당신 ' 대신)로 설정했습니다 strong. 예를 들어 Matt Neuburg의 글을 읽어 iOS 7 Programming Fundamentals보면 델리게이트를 속성으로 선언하는 클래스가 '약하게, 공평 해 보이는'상태를 유지할 수 있음을 보여줍니다.
Bogdan Alexandru

2

마지막 두 질문에 명시 적으로 대답하는 Robert가 참조한 문서의 일부를 호출하려면 다음을 수행하십시오.

// The following declaration is similar to "@property(assign) MyClass *myObject;"
// except that if the MyClass instance is deallocated,
// the property value is set to nil instead of remaining as a dangling pointer.
@property(weak) MyClass *myObject;

이를 제로화 약한 참조라고합니다. __unsafe_unretained를 사용하여 약한 참조를 제로화하지 않는 약한 참조를 만들 수 있지만 이름에서 알 수 있듯이 일반적으로 권장되지 않습니다.

또한 문서에서 :

Weak references are not supported in Mac OS X v10.6 and iOS 4.

1
예, 맞습니다 . __unsafe_unretained의 ARC 버전입니다 assign.
로버트

2

WEAK 속성의 명확한 사용은 다음과 같습니다.

Any control whose properties we need to change(eg:text of a label) is declared weak and as below:

@property(nonatomic,weak) IBOutlet Type *name;
Eg: @property(nonatomic,weak) IBOutlet UILabel *myLabel;

1
내 속성에 weak를 사용하면 "Weak receiver가 예기치 않게 nil로 설정 될 수 있습니다"라는 경고가 표시됩니다. 이 경고를 방지하기 위해 로컬 강력한 참조를 만들어야하는 다른 게시물을 보았습니다. 그리고 이것이 사실이라면, 마지막에 강한 참조를 만들어야한다면 속성을 약하게 만드는 요점이 무엇일까요?
arh

0

더 자세히 설명하기 위해 예를 들어 보겠습니다 (위의 답변은 이미 훌륭합니다),이 예가 조금 더 도움이 될 수 있습니까?

클래스 A와 B를 두 개

//A.h

#import <Foundation/Foundation.h>
#import "B.h"

@interface A : NSObject

@property (nonatomic, strong) B *objB;

@end

@implementation A
//

@end

//B.h

    #import <Foundation/Foundation.h>
    #import "A.h"


    @interface B : NSObject

    @property strong text(nonatomic, strong) A *objA;

    @end

    @implementation B
    //

    @end

    and in main

    #import "B.h"
    #import "A.h"

    {
    A *obja =[[A alloc]init];
    B *objb =[[B alloc]init];
    A.objB=objb;
    B.objA=obja;
   }

위 코드는 둘 다 강력한 유형 a --------> b ---------> a이기 때문에 유지주기를 생성합니다.

그래서 그것을 피하기 위해 당신은 그것 중 하나의 주 속성을 사용하여 매주 개체를 참조하고 참조 횟수를 늘리지 않도록해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.