본문 바로가기
프로그래밍 놀이터/iOS

[Objective-C] performSelector: 가 경고를 뿜는다?

by 돼지왕왕돼지 2017. 12. 9.

 [Objective-C] performSelector: 가 경고를 뿜는다?


http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown


arc, compile time, COPY, function pointer, imp, init, manual memory management, memory leak, method call, methodForSelector, new, nsinvocation, NSSelectorFromString, objc_msgSend, performSelector, release, Runtime, SEL, selector, Swift, unsafe, [Objective-C] performSelector: 가 경고를 뿜는다?


-

Manual Memory Management 시절에서는 performSelector: 가 OK!!



-

ARC 의 등장으로 performSelector: 는 경고를 내뿜게 되었고..



-

Swift 에서는 performSelector: 를 접근하지 못하게 하고, 문서에도 unsafe 하니 쓰지 말라고 해놓았다.



-

ARC 이후에 performSelector: 를 쓰고 싶다면 이런 방식으로 사용하는 것이 권장된다.

ARC 가 detect 하지 못하는 C level 함수 콜 형태로 바꾸는 것이다.

SEL selector = NSSelectorFromString(@“someMethod”);

IMP imp = [_controller methodForSelector:selector]; // C function pointer get

void (*func)(id, SEL) = (void *)imp;

func(_controller, selector);



-

return 값이 있는 경우는 다음과 같이...

SEL selector = NSSelectorFromString(@“processRegion:ofView:”);

IMP imp = [_controller methodForSelector:selector];

CGRect (*funct)(id, SEL, CGRect, UIView*) = (void *)imp;

CGRect result = func(_controller, selector, someRect, someView);



-

경고가 나오는 이유는 ARC 가 해당 method call 에 대한 result 를 어떻게 처리하는지 모르기 때문이다.

왜냐면 ARC 는 Compile Time 에 적용되고, performSelector: 는 Runtime 에서 결정되어 적용되는 녀석이기 떄문이다.

ARC 가 관여하지 않는 C level 의 함수콜로 대체하여 warning 을 없앨 수 있다.



-

performSelector: 대신에 objc_msgSend(someObject, selector) 를 사용하는 방법도 warning 을 막을 수 있다.


NSInvocation 방법도 있다.


경고를 아예 무시하는 compiler 지시자를 통해서 그냥 경고를 무시할 수도 있다.



-

일반적으로 performSelector: 를 사용하는 것이 문제가 없지만,

copy, new, init 등과 같은 접두사를 가진 메소드를 호출할 때는 ARC 가 return 되는 값들을 release 시켜주지 않기 때문에 memory leak 의 위험성이 있다.





댓글0