1

나는 다음과 같은 몇 가지 코드를 가지고 : 매우 자주C++에서 Obj-C 메시지를 호출 할 때 자동 보유/해제를 방지하려면?

@interface MyTimer : NSObject 
- (int)getValue; 
@end 

@interface TimerHolder : NSObject { 
    ExternalControl* m_externalControl; 
} 
@property (retain, nonatomic) MyTimer* timer; 
@end 

class ExternalControl { 
    __unsafe_unretained TimerHolder* m_holder; 
public: 
    ExternalControl(TimerHolder* holder) : m_holder(holder); 
    int getTimer() { return [m_holder.timer getValue] }; 
}; 

방법 ExternalControl::getTimer()라고합니다. 프로파일 링 중에 getTimer() 호출 중에 obc-j도 objc_retainobjc_release (아마도 m_holder 또는 m_holder.timer에 있음)을 호출하여 많은 시간을 빨아들이는 것으로 나타났습니다. __unsafe_unretained을 제거해도 효과가 없습니다.

구성에 따라 ExternalControl::getTimer()이 호출 될 때마다 m_holder와 해당 타이머가 통화 기간 동안 지속되므로 보유/릴리스가 필요 없다고 생각합니다.

전화를 걸 수있는 방법이 있습니까?

저는 ARC가 활성화 된 iOS 5 SDK와 함께 XCode 4.2를 사용하고 있습니다. ARC의 책임은 무엇이며이를 제거하면 보관/해지가 제거됩니까? (내 친구들과 함께 확인하기 전에 ARC가없는 프로젝트를 다시 작성하여 시간을 보내고 싶지 않다.)

+1

내게이 코드는 ARC 규칙 중 하나를 위반하는 것처럼 보입니다. 즉, C 구조 (이 경우 C 구조로 계산되는 C++ 클래스)에 oject 포인터를 저장하지 마십시오. 따라서 적절한 대답은이 파일에 대해 ARC를 사용하지 않는 것입니다. http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html – JeremyP

+0

의견을 대답 대신 답으로 쓰지 않으시겠습니까? – squelart

+0

왜 기억하지 못합니다. 아마도 나는 그 질문에 적절히 대답하지 못했을 것입니다. 그때 나는 ARC 프로그래밍을하지 않았습니다. – JeremyP

답변

1

ARC가 아닌 환경에서는 내가 사용하지 않았기 때문에 말할 수있다. 아직 (그리고 오래된 학교가 아닌 계획).

그러나 C++ 라이브러리를 사용하고 obj-C 코드에서이 프로젝트에 대한 참조를 유지하는 프로젝트가 여러 개 있습니다. 명시 적으로 요청하지 않는 한 retain/release가 호출되지 않는다는 사실을 알고 있습니다.

BTW, C++ 라이브러리를 링크 할 때 Obj-C를 사용할 수 없으며 대신 Obj-C++을 사용해야합니다. 그렇지 않으면 C++ 생성자/소멸자가 예상대로 호출되지 않았습니다. .m 파일의 이름을 .mm으로 바꾸는 문제였습니다

희망이 도움이됩니다.

+0

고마워요, 그게 범인으로 ARC를 가리키는 것 같습니다. 예 Obj-C++을 사용하고 있습니다. – squelart

+0

ARC가 제거되어 추가 보유/릴리스가 사라졌습니다. – squelart

2

해당 클래스의 유지/릴리스를 수동으로 처리하려면 (ARC 사용 안 함). 해당 소스 파일의 빌드 단계 탭에서 "-fno-objc-arc"컴파일러 플래그를 설정하십시오.

0

ARDC에 대한 WWDC 2011 세션에서는 디버그 용으로 컴파일 될 때 ARC 유지/릴리스가 최적화되지 않는다고 구체적으로 언급합니다.

아직 릴리스 모드에서 코드를 실행하고 프로파일 링 해보십시오. 중요한 차이가 나타납니다.

그러나 ARC는 "건설 별"이라고 말할 때 암시하는 디자인 가정의 종류를 고려하지 않습니다. 하지만 ARC가 "__unsafe_unretained"인스턴스 변수를 건드려서는 안됩니다 ... retain/release 호출에 에 대한 포인터가 전달되고 있습니까?

+0

방금 ​​확인한 "프로필"구성표가 기본적으로 릴리스 모드로 빌드됩니다. 그래서 저는 그들이이 특별한 사용법을 최적화하지 않는다고 추측합니다 ...Obj-C 객체가 파괴 된 동안 내 C++ 코드를 실행할 수 없다는 보장이 없기 때문에 공정하게 보입니다. 그래서 컴파일러에게 내 의도를 어떻게 든 말할 수 없다면이 retain/release를 제거 할 수 없습니다. . – squelart

+0

하지만 "__unsafe_unretained"는 의도에 대해 알려주고 있습니다 ... ARC가 그/그녀를 설정하려고했던 계약을 위반하는 행동을 유지하려고 시도하고 있다는 것을 알기 위해 나는 놀라게 될 것입니다. 뭔가 다른 일이 벌어지고 있습니다. – Steve

+0

내가 이해 한 바로는 __unsafe_unretained는이 변수에 포인터가 포함되어 있으며 pointee가 삭제되면이 포인터가 자동으로 제로화되지 않는다고 컴파일러에 알립니다. 따라서 컴파일러는 객체를 유지함으로써 사용자를 보호하려고 시도하므로 릴리스가 사용되는 동안 릴리스를 방지합니다. 제 의도는 컴파일러에게 "__unsafe_retained"와 같은 것을 알려주는 것입니다. 여기서 나는 그 객체가 다른 곳에서 유지되어야한다는 것을 알고 있기 때문에 저를 위해 그것을 유지할 필요가 없습니다. :-) – squelart