2014-06-07 1 views
8

ARC를 사용하지 않는 매우 큰 레거시 Objective-C 프로젝트에 Swift 파일을 추가하기 시작했습니다. 내가 프로젝트를 컴파일 할 때Swift는 이전 ARC Objective-C와 호환되지 않습니까?

, 내가 ProjectName-Swift.h 다리 헤더에 방출되는 모든 속성에 대한 경고를 얻을 :

  • 없음 '할당', '유지'또는 '복사'속성이 지정 - '할당'입니다
  • 기본 속성 속성 비 GC 객체

그것은 ARC 기반 오브젝티브 C 코드를 방출한다 스위프트 같아 적합하지 '할당'을 가정 하였다.

이 특정 릴리스의 Swift에서 제한/버그입니까? 아니면 신속하게 ARC 코드에서만 작동하도록 설계 되었습니까?

+3

아직 ARC를 사용하지 않는 이유가 무엇인지 알 수 없습니다. 나는 그것이 레거시 코드이지만, 레거시 코드는 업데이트되어야한다 ... –

+0

"MRC"라 불리는 "pre-ARC"의 시대는 아마도 당신이 무엇을 사용하고 있는지를 아는 것이 좋다. – holex

+5

@LordZsolt 사전 ARC 메모리 관리 체제 하에서 잘 테스트 된 대규모 코드베이스에 불필요하게 메모리 관리 버그가 발생하는 것을 방지합니다. – Bill

답변

10

ARC 코드와 비 ARC 코드를 혼합하여 사용할 수 있습니다. 모든 ARC로 컴파일 된 코드는 사용자에게 자동으로 메모리를 관리합니다. 프로젝트에 대해 ARC를 활성화 한 다음 -fno-objc-arc을 사용하여 개별 파일에 대한 ARC를 비활성화하거나 -fobjc-arc을 사용하여 Swift 파일에 대해 ARC를 활성화하십시오 (컴파일러가 자동으로 추가 할 수 있으므로 필요하지 않을 수도 있음). Swift 코드는 결국 같은 Objective C 런타임을 사용하도록 컴파일되고 컴파일러에서 삽입 된 ARC 호출은 Objective C와 동일합니다. 컴파일 후 ARC 및 비 ARC 코드는 동일하게 작동합니다.

+0

당신이 쓰는 모든 것은 정확하지만 질문과는 아무런 관련이 없습니다. 문제는 컴파일러가 헤더 파일을 읽는 "after"가 아니라 "compile time 중"이 아니며 Swift가 생성하는 헤더 파일은 항상 ARC를 가정하므로 헤더 파일을 ARC가 아닌 클래스에서 사용하면 객체가 올바르게 작동합니다. 컴파일, 문제는 없지만 컴파일러는이 헤더를 가져 오는 비 ARC 파일에 대해 경고를 던지고 헤더가 올바르지 않으며 그것이 단지 방법 일 뿐이므로 어떤 해결책도 찾을 수 없습니다. – Mecki

+0

"정확하지 않다"는 의미는 무엇입니까? '약한'과'강한'과 같은 ARC가 의도 한 수식어를 의미합니까? –

+0

속성에 저장 속성이 없다면 ARC가 아닌 곳에서는'assign'이지만 ARC에서는'retain' /'strong'입니다. 그래서 ARC와 non-ARC Obj 둘 다에서 같은 헤더 파일을 사용하고 싶다면 -C 파일을 사용하려면 항상 명시 적 저장소 특성을 사용해야합니다. 그렇지 않으면 컴파일러는 일단 이것이 'assign'속성이라고 생각하면이 속성은 'strong'속성이지만 실제로는 둘 중 하나 일 수 있습니다. 가정은 항상 거짓입니다. Swift는'strong' 변수에 대한 속성을 설정하지 않으므로 Swift는 헤더 파일이 ARC 코드에서만 사용된다고 가정합니다. – Mecki

0

When I compile the project, I get warnings for every property emitted in the ProjectName-Swift.h bridge header

모든 파일을 ARC로 변환하면 경고를 없앨 수있었습니다. (-fno-objc-arc을 사용하지 않음)

0

Swift가 Obj-C 용으로 생성하는 헤더 파일은 Obj-C 코드에서 ARC가 사용되고 있다고 가정합니다. Xcode 버전 및 빌드 설정에 따라 속성이 암시 적으로 assign -property 일 때마다 경고하는 경고가 활성화되어있을 수 있습니다.이 속성은 ARC 코드와 같이 비 ARC 코드에서만 발생하며 속성은 암시 적으로 strong입니다. 비 ARC 코드에서 retain과 정확히 동일). 해당 경고가 활성화되면 생성 된 헤더를 ARC가 아닌 .m 파일로 가져올 때마다 경고 메시지가 표시되고 Swift는 해당 속성에 대한 저장 속성을 설정하지 않습니다.

그러나 경고는 나중에 컴파일 된 코드가 제대로 작동하지 않음을 의미하지 않습니다. 컴파일러는 weak -Properties가 될! 그들은 strong 수 있습니다 또는이 weak (weakassign과 동일하지 않습니다 될 수 있으며,이 건물은이 assign 같은 스위프트 특성도 assign하지 않을 수 없을 확실히 않습니다 만 assign 믿고 있다는 사실에도 불구하고 nil 개체가 죽으면 assign -properties가 포인터를 매달고 여전히 개체가 살던 데 사용 된 주소를 가리 킵니다. 경고에도 불구하고이 상황이 발생할 수있는 최악의 상황은 잘못된 정적 코드 분석기 결과입니다.이 assign -property가 코드를 손상시킬 수 있고 다시 분석기가 실수로 assign이 아닌 것으로 경고합니다. 현실.

그 문제를 해결하려면, 요구 된 유일한 것은 기본적으로 무엇이든 항상 올바르게 또한 비 ARC 코드 ( strongretain에서 작동 strong, 모든 속성을 태그있는 속성에 의존하지 않습니다 단지 동의어 않을 것입니다 컴파일러는 정확히 똑같이 취급하므로 둘 다 비 ARC 코드에서 사용할 수 있습니다). 웃기는 일은 바로 스위프트가하는 일입니다. 생성 된 헤더에 많은 수의 strong 속성이 있지만 분명히 Swift가 수행하지 않는 상황이 있습니다 (실제로는 Swift 버그입니다).

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wobjc-property-no-attribute" 
#import "xxx-Swift.h" 
#pragma clang diagnostic pop 

그냥 다른 헤더 파일, 예를 들어,에 그 팩을 다음과 같이 수행 할 수 있습니다 생성 된 헤더를 가져올 때 그 문제에 대한

쉬운 일-A-라운드는 경고를 비활성화하는 것입니다 My-xxx-Swift.h을 입력 한 다음 코드에서 My-xxx-Swift.h 만 가져 오십시오.

일반적으로이 경고가 의미가 있으며 ARC와 비 ARC 코드를 혼합 할 때 끔찍한 버그를 예방하는 데 도움이 될 수 있으므로 전체 프로젝트 (예 : Xcode 빌드 설정)에서는 비활성화하지 않겠습니다 ARC와 비 ARC를 혼합 할 때 절대적으로 저장소 특성을 갖고 있지 않으므로 암시 적 특성에 의존하지 말고 항상 저장소를 명시 적으로 지정하는 것이 좋습니다.

관련 문제