2010-06-14 4 views

답변

9

저는 약간의 추측을하고 모든 사람들과 동의하지 않을 것입니다. 한 언어로 가능한 모든 것이 다른 언어 (가능하면 "계산 가능"을 의미)에서 가능하다는 것은 기술적으로 사실이지만 은 쉽게을 표현할 수있는 점에서 다릅니다. 컴퓨터가 C로 작성한 코드에 대한 응답으로 동일한 작업을 수행하고있을 수도 있지만 은 이러한 작업을 수행하기 위해 근본적으로 다른 코드를 작성하고 있습니다.

다른 사람들처럼 Objective-C는 Objective-C 데이터 구조를 만들고 C 함수를 호출 할 수있는 C로 작성된 전체 런타임 라이브러리를 제공하지만이를 수행하는 코드는 매우 자세하고 원형이며 완전히 명령적이다. Objective-C에서이 코드는보다 선언적이며 간결하고 훨씬 읽기 쉽습니다.

일반적으로 C로 Objective-C를 작성하려고하면 언어가 관용적으로 사용되는 것보다 코드가 악화됩니다.

@interface NumberAdder : NSObject { 
    int storedValue; 
} 

- (id)initWithStoredValue:(int)value; 
- (int)resultOfAddingStoredValue:(int)numberToAdd; 
@end 

@implementation NumberAdder 
- (int)resultOfAddingStoredValue:(int)numberToAdd { 
    return numberToAdd + storedValue; 
} 

- (id)initWithStoredValue:(int)value { 
    if (!(self = [super init])) return nil; 
    storedValue = value; 
    return self; 
} 
@end 

int main() { 
    id adder = [[NumberAdder alloc] initWithStoredValue:4]; 
    int result = [adder resultOfAddingStoredValue:3]; 
    printf("It is %d\n", result); 
    return 0; 
} 

을 그리고 여기에 목표 - C 런타임과 C로 작성 같은 일입니다 (테스트하지,하지만 거의 정확해야) : 예를 들어, 다음 목표 - C로 작성된 간단한 프로그램입니다

int returnPlusStoredValueImp(id self, SEL _cmd, int arg) { 
    int *storedValue = nil; 
    object_getInstanceVariable(self, "storedValue", &storedValue) 
    return arg + *storedValue; 
} 

id numberAdderInit(id self, SEL _cmd, int valueToStore) { 
    objc_super superInfo = {self, objc_lookupClass("NSObject")}; 
    self = objc_msgSendSuper(super_info, sel_getName("init")); 
    if (!self) return nil; 
    object_setInstanceVariable(self, "storedValue", &valueToStore); 
    return self; 
} 

void createNumberAdderClass() __attribute(constructor)__ { 
    Class NumberAdder = objc_allocateClassPair(objc_lookupClass("NSObject"), "NumberAdder", 0); 
    if (!NumberAdder) return; 
    class_addIvar(NumberAdder, "storedValue", sizeof(int), 4, "i"); // I'm actually not sure if the fourth argument is correct, so it's probably wrong, but just take that as a sign of how much this way of coding sucks 
    objc_registerClassPair(NumberAdder); 
    SEL nameOfPlusStoredValue = sel_registerName("resultOfAddingStoredValue:"); 
    SEL nameOfInit = sel_registerName("initWithStoredValue:"); 
    class_addMethod(NumberAdder, nameOfPlusStoredValue, returnPlusStoredValueImp, "[email protected]:i"); 
    class_addMethod(NumberAdder, nameOfInit, numberAdderInit, "@@:i"); 
} 

int main() { 
    id adder = objc_msgSend(objc_lookupClass("NumberAdder"), sel_getName"alloc"); 
    adder = objc_msgSend(adder, sel_getName("initWithStoredValue:"), 4); 
    int result = (int)objc_msgSend(adder, sel_getName("resultOfAddingStoredValue:"), 3); 
    printf("It is %d\n", result); 
    return 0; 
} 
+1

+1 하드 라인을 데리고 그것을 보여줍니다. 좋은 대답. – bbum

+0

사실상 +2입니다. 왜냐하면 더 높은 "언어 구조"에 대한 필요성이 없기 때문에 컴퓨터 언어 주위의 모든 부분이이 (또는 그 주변)이기 때문에 우리 모두가 여전히 어셈블리를 사용할 것이기 때문입니다. – ShinTakezou

1

그런 것은 아닙니다. 일반적으로 모든 프로그래밍 언어로 모든 것을 프로그래밍 할 수 있습니다.

+5

"무엇이든"많은 것을 버려야 만. – danben

+1

환상적입니다. 귀하의 해결책을 정지 문제에 게시 할 수 있습니까? http://en.wikipedia.org/wiki/Halting_problem – JeremyP

+0

정말 Sjoerd? 다음과 같은 프로그래밍 언어 하나만 있으면됩니다!/풍자 – Jage

8

아무 것도 아닙니다. Objective-C의 OO 기능은 C로 작성된 작은 런타임 라이브러리로 구현됩니다.

일부 의견 작성자는 Objective-C가 블록을 가지고 있으며 C가 그렇지 않다는 것을 지적하지만 실제로는 C의 GCC/LLVM 확장입니다. Objective-C는 ObjC 기능을 사용하지 않습니다.

+2

gcc가 실행 가능한 스택을 필요로하기 때문에 종종 사용을 피하는 것이 좋다. 스택 프레임을 복원하여 범위 네 스팅이 작동하도록하려면 트램펄린은 약간의 마법을 수행하는 작은 함수입니다. P) 실행 스택을 사용할 수 없습니다 ... 예를 들어 NX를 켠 상태에서 (gcc는 madvise 또는 뭔가 그래도 작동 할 것입니다 ... 어쩌면) – Spudd86

+2

Graham의 잘 만들어진 점에 추가하기 위해 작은 런타임 라이브러리는 사용하도록 허용 된 C 함수 세트로 노출됩니다. 즉, Objective-C를 사용하지 않고 Objective-C 라이브러리를 사용할 수도 있습니다. 여기를 참고하십시오 : http://developer.apple.com/mac/library/documentation/cocoa/reference/objcruntimeref/Reference/reference.html – harms

+3

블록 - Mac OS X에서 구현 된대로 - 절대적으로 * 실행하지 않아도 * 않습니다. 스택. 그것은 그들의 설계에서 요구 사항이었습니다. – bbum

3

Graham이 말했듯이 Objective-C에서는 C로 수행 할 수없는 일은 절대적으로 없습니다. 물론 C에서 수행 할 수있는 작업은 없습니다. 조립할 수 있습니다. 그것은 타이핑의 문제 일뿐입니다.

(필자는 조립 언급 것을 표시하기에 충분 될 것이라고 기대했다, 아니, 내가 원격으로 순수 C에서 그 서 OO 패턴을 제시하고 있지 않다 원격으로 할 수있는 생산적인 일입니다 ...) 관심의 몇 가지 추가 사항이 있습니다

  • 오브젝티브 C는 표준 C 컴파일러로 컴파일 될 수있는 C 코드로 목표 - C 코드를 설정 프리 프로세서로 시작. 즉, Objective-C는 원래 직접적으로 컴파일되지 않았지만 C로 변환 된 다음 컴파일되었습니다.

  • Objective-C 객체는 구조의 첫 번째 항목 (isa)이 구조/인스턴스를 설명하는 메타 데이터 (Class)에 대한 포인터 인 C 구조로 생각할 수 있습니다.

  • 블록은 C의 확장이며 이제 WG-14 (C 표준위원회)의 C 언어에 추가되었습니다. Apple이 구현 한 블록은 이 아니며에는 실행 스택이 필요합니다. 그들의 디자인에있어 어려운 요구 사항이었습니다.

  • LLVM에는 실제로 Objective-C를 C로 다시 쓸 수있는 rewriter가 있으며 분명히 Xbox 360 게임에서 Objective-C 코딩을 사용하는 데 사용되었습니다 (http://permalink.gmane.org/gmane.comp.compilers.llvm.devel/31996 참조).

+0

입력의 문제가 없습니다. HL 구문과 다른 패러다임은 "다르게 생각하는"데 도움이되며 문제에 대한 인식을 변화시킵니다 (그리고 솔루션을 찾는 방식을 바꿉니다). 그것들은 도구이기 때문에 당신은 같은 높이에 도달 할 수 없습니다. 대성당을 짓는 것은 벽돌 위에 벽돌을 두는 방법을 알고 1 미터 높이의 첫 번째 벽돌집을 짓는 데 사용한 것과 같은 도구를 사용하는 것으로 충분하다고 생각할 수 없습니다. 다시 타이핑을 시작하면 곧 당신은 당신이 이미 가지고있는 도구들을 재구성하고 쓰고 있습니다. 그러나 일단 당신이 그것을하면, 당신은 그들이 계속할 필요가 있음을 확인하고 있습니다 .cycle – ShinTakezou

+0

@ShinTakezou 나는 당신과 내가 폭력적인 합의에 있다고 믿습니다. 나는 직설적 인 C로 OO 코드를 작성하는 것이 합리적인 해결책이라는 것을 암시하지 않았다. – bbum

관련 문제