[c#] Objective-C는 C #과 어떻게 다릅니 까? [닫은]

최근에 Mac을 구입했으며 주로 VMWare Fusion에서 C # 개발에 사용합니다. 주변의 모든 멋진 Mac 응용 프로그램과 함께 Xcode가 설치 클릭 한 번으로 숨어있는 것을 생각하고 Objective-C를 배우기 시작했습니다.

Objective-C는 C에서 기원하고 C #은 Java / C ++에서 기원하기 때문에 두 언어 간의 구문은 매우 다르게 보입니다. 그러나 다른 구문을 배울 수 있으므로 괜찮습니다.

내 주요 관심사는 언어로 작업하고 잘 구조화되고 읽기 쉽고 우아한 코드를 생성하는 데 도움이되는지 여부입니다. 저는 C #의 LINQ 및 var와 같은 기능을 정말 좋아하고 Objective-C에 동등하거나 더 나은 / 다른 기능이 있는지 궁금합니다.

Objective-C로 개발할 때 놓친 언어 기능은 무엇입니까? 어떤 기능을 얻을 수 있습니까?

편집 : 프레임 워크 비교는 유용하고 흥미롭지 만 언어 비교는이 질문이 실제로 묻는 것입니다 (부분적으로 원래 태그에 대한 내 잘못입니다 .net). 아마도 Cocoa와 .NET은 그 자체로 매우 풍부한 프레임 워크이며 둘 다 목적이 있습니다. 하나는 Mac OS X를 대상으로하고 다른 하나는 Windows를 대상으로합니다.

지금까지 잘 생각하고 합리적으로 균형 잡힌 견해에 감사드립니다!



답변

모든 작업에 완벽한 언어는 없으며 Objective-C도 예외는 아니지만 매우 구체적인 장점이 있습니다. LINQand var(내가 직접 대체하는 것을 알지 못함) 사용 과 마찬가지로 이들 중 일부는 엄격하게 언어와 관련이 있고 다른 일부는 프레임 워크와 관련됩니다.

( 참고 : C #이 .NET과 밀접하게 결합 된 것처럼 Objective-C는 Cocoa와 밀접하게 결합되어 있습니다. 따라서 내 요점 중 일부는 Objective-C와 관련이없는 것처럼 보일 수 있지만 Cocoa가없는 Objective-C는 .NET이없는 C #과 비슷합니다. WPF / LINQ, Mono 등에서 실행. 일반적으로 수행되는 방식이 아닙니다.)

차이점, 장단점을 완전히 설명하는 척하지는 않겠지 만, 여기에 떠오르는 몇 가지 사항이 있습니다.

  • Objective-C의 가장 좋은 부분 중 하나는 동적 특성입니다. 메서드를 호출하는 대신 런타임이 동적으로 라우팅하는 메시지를 보냅니다. 동적 타이핑과 (현명하게) 결합하면 많은 강력한 패턴을 구현하기가 더 간단하거나 사소하게 만들 수 있습니다.

  • C의 엄격한 상위 집합으로서 Objective-C는 사용자가 무엇을하고 있는지 알고 있다고 신뢰합니다. C # 및 Java와 같은 언어의 관리 및 / 또는 유형 안전 접근 방식과 달리 Objective-C를 사용하면 원하는 작업을 수행하고 그 결과를 경험할 수 있습니다. 분명히 이것은 때때로 위험 할 수 있지만 언어가 대부분의 작업을 적극적으로 방해하지 않는다는 사실은 매우 강력합니다. ( 편집 : C #에도 “안전하지 않은”기능과 기능이 있음을 명확히해야하지만 기본 동작은 명시 적으로 옵트 아웃해야하는 관리 코드입니다. 이에 비해 Java 는 형식이 안전한 코드 허용하며 원시 포인터를 노출하지 않습니다. C와 다른 사람들이하는 방식.)

  • 카테고리 (서브 클래 싱없이 클래스에 메서드 추가 / 수정 또는 소스에 대한 액세스 권한이 없음)는 멋진 양날의 검입니다. 상속 계층 구조를 대폭 단순화하고 코드를 제거 할 수 있지만 이상한 작업을 수행하면 결과가 당황 스러울 수 있습니다.

  • Cocoa는 여러 가지 방법으로 GUI 앱을 훨씬 더 간단하게 만들 수 있지만, 패러다임에 머리를 감아 야합니다. MVC 디자인은 Cocoa에서 널리 사용되고 있으며 델리게이트, 알림 및 다중 스레드 GUI 앱과 같은 패턴은 Objective-C에 적합합니다.

  • Cocoa 바인딩 및 키-값 관찰은 수많은 글루 코드를 제거 할 수 있으며 Cocoa 프레임 워크는이를 광범위하게 활용합니다. Objective-C의 동적 디스패치는 이와 함께 작동하므로 키-값을 준수하는 한 객체의 유형은 중요하지 않습니다.

  • 제네릭과 네임 스페이스를 놓칠 가능성이 높고 이점이 있지만 Objective-C 사고 방식과 패러다임에서는 필수품이 아니라 멋짐 일 것입니다. (제네릭은 유형 안전성과 캐스팅 방지에 관한 것이지만, Objective-C의 동적 타이핑은 본질적으로 문제가되지 않습니다. 네임 스페이스는 잘 수행하면 좋겠지 만, 비용이 이점을 능가하는 충돌을 피할 수있을만큼 간단합니다. 특히 레거시 코드의 경우.)

  • 동시성을 위해 Blocks (Snow Leopard의 새로운 언어 기능이며 수많은 Cocoa API에 구현 됨)는 매우 유용합니다. 몇 줄 (자주 10.6에서 libsystem의 일부인 Grand Central Dispatch와 결합 됨)은 콜백 함수, 컨텍스트 등의 중요한 상용구를 제거 할 수 있습니다. (블록은 C 및 C ++에서도 사용할 수 있으며 확실히 C #에 추가 될 수 있습니다. NSOperationQueue는 또한 GCD가 하나 이상의 다른 스레드에서 자동으로 실행되는 사용자 지정 NSOperation 하위 클래스 또는 익명 블록을 발송하여 자신의 코드에 동시성을 추가하는 매우 편리한 방법입니다.


답변

저는 1990 년에 처음 시작된 20 년 넘게 C, C ++ 및 C #으로 프로그래밍했습니다. 방금 iPhone 개발과 Xcode 및 Objective-C를 살펴보기로 결정했습니다. 오, 세상에 .. 마이크로 소프트에 대한 모든 불만을 되찾았고, 이제 코드가 얼마나 나쁜지 깨달았습니다. Objective-C는 C #이하는 일에 비해 너무 복잡합니다. 나는 C #에 푹 빠졌고 지금은 마이크로 소프트가 투입 한 모든 노력에 감사드립니다. 메소드 호출로 Objective-C를 읽는 것은 읽기 어렵습니다. C #은이 점에서 우아합니다. 그것은 제 의견 일뿐입니다. 저는 Apple 개발 언어가 Apple 제품만큼 좋기를 바랐지만, 저에게도 Microsoft로부터 배울 것이 많습니다. C # .NET 응용 프로그램은 XCode Objective-C보다 몇 배 더 빠르게 응용 프로그램을 설치하고 실행할 수 있습니다. 애플은 확실히 여기 마이크로 소프트의 책에서 잎사귀를 꺼내야한다. 그러면 우리는 완벽한 환경을 갖게 될 것이다. 🙂


답변

여기에 기술적 인 리뷰는 없지만 Objective-C가 훨씬 읽기 어렵습니다. Cinder6이 제공 한 예가 다음과 같습니다.

씨#

List<string> strings = new List<string>();
strings.Add("xyzzy");                  // takes only strings
strings.Add(15);                       // compiler error
string x = strings[0];                 // guaranteed to be a string
strings.RemoveAt(0);                   // or non-existant (yielding an exception)

목표 -C

NSMutableArray *strings = [NSMutableArray array];
[strings addObject:@"xyzzy"];
[strings addObject:@15];
NSString *x = strings[0];
[strings removeObjectAtIndex:0];

끔찍해 보입니다. 두 권의 책을 읽으려고했는데, 그들은 일찍부터 나를 잃었고, 보통은 프로그래밍 책 / 언어로는 이해하지 못합니다.

좋은 개발 환경을 제공하기 위해 Apple에 의존해야했다면 Mac OS 용 Mono를 사용하게되어 기쁩니다.


답변

수동 메모리 관리는 Objective-C를 처음 접하는 사람들이 가장 문제가 많은 것 같습니다. 대부분은 그것이 실제보다 더 복잡하다고 생각하기 때문입니다.

Objective-C와 Cocoa는 확장을 통해 시행에 대한 관습에 의존합니다. 아주 작은 규칙 세트를 알고 따르면 동적 런타임으로 많은 것을 무료로 얻을 수 있습니다.

100 % 진정한 규칙은 아니지만 매일 사용하기에 충분합니다.

  • 모든 호출 은 현재 범위의 끝에 alloc있는와 일치해야합니다 release.
  • 당신의 방법의 반환 값에 의해 획득 된 경우 alloc그것은에 의해 반환되는 return [value autorelease];대신 일치되고 release.
  • 속성을 사용하면 세 번째 규칙이 없습니다.

더 긴 설명이 이어집니다.

메모리 관리는 소유권을 기반으로합니다. 객체 인스턴스의 소유자 만이 객체를 해제 해야하며 다른 모든 사람은 항상 아무것도하지 않아야합니다. 이것은 모든 코드의 95 %에서 Objective-C를 가비지 수집 된 것처럼 취급한다는 것을 의미합니다.

그러면 나머지 5 %는 어떻습니까? 찾아야 할 세 가지 메서드가 있으며 이러한 메서드에서받은 모든 개체 인스턴스는 현재 메서드 범위 가 소유합니다 .

  • alloc
  • 모든 방법은 단어로 시작하는 와 같은, new또는 newService.
  • copy라는 단어가 포함 된 모든 메서드 (예 : copymutableCopy.

메소드는 종료하기 전에 소유 한 객체 인스턴스로 수행 할 수있는 세 가지 옵션이 있습니다.

  • release더 이상 필요하지 않은 경우 사용하여 해제하십시오 .
  • 필드 (인스턴스 변수) 또는 전역 변수에 간단히 할당하여 소유권을 부여합니다.
  • 소유권을 포기하지만을 호출하여 인스턴스가 사라지기 전에 다른 사람이 소유권을 가질 수있는 기회를 제공 autorelease합니다.

그렇다면 언제 사전에 전화하여 소유권을 가져와야 retain합니까? 두 가지 경우 :

  • 이니셜 라이저에 필드를 할당 할 때.
  • setter 메서드를 수동으로 구현할 때.


답변

물론, 당신이 당신의 삶에서 본 모든 것이 Objective C라면, 그 구문은 유일한 가능한 것처럼 보입니다. 우리는 당신을 “프로그래밍 처녀”라고 부를 수 있습니다.

그러나 많은 코드가 C, C ++, Java, JavaScript, Pascal 및 기타 언어로 작성 되었기 때문에 ObjectiveC가 모든 언어와 다르지만 좋은 방식은 아닙니다. 이유가 있었나요? 다른 인기있는 언어를 살펴 보겠습니다.

C ++는 C에 많은 추가 기능을 추가했지만 원래 구문을 필요한만큼만 변경했습니다.

C #은 C ++에 비해 많은 추가 기능을 추가했지만 C ++에서보기 흉한 부분 만 변경했습니다 (예 : 인터페이스에서 “::”제거).

Java는 많은 것을 변경했지만 변경이 필요한 부분을 제외하고는 익숙한 구문을 유지했습니다.

JavaScript는 ObjectiveC가 할 수없는 많은 일을 할 수있는 완전히 동적 인 언어입니다. 그래도 제작자는 다른 세계와 다르기 위해 메서드를 호출하고 매개 변수를 전달하는 새로운 방법을 발명하지 않았습니다.

Visual Basic은 ObjectiveC와 마찬가지로 순서없이 매개 변수를 전달할 수 있습니다. 매개 변수의 이름을 지정할 수 있지만 일반적인 방법으로 전달할 수도 있습니다. 무엇을 사용하든 모두가 이해할 수있는 일반적인 쉼표로 구분 된 방법입니다. 쉼표는 프로그래밍 언어뿐만 아니라 일반적으로 책, 신문 및 서면 언어에서 일반적인 구분 기호입니다.

오브젝트 파스칼은 C와는 다른 구문을 가지고 있지만 그 구문은 실제로 프로그래머가 읽기가 더 쉽습니다 (컴퓨터가 아니라 컴퓨터가 생각하는 것을 누가 신경 쓰는지). 그래서 아마도 그들은 탈락했지만 적어도 그들의 결과는 더 좋습니다.

파이썬은 파스칼보다 더 읽기 쉬운 다른 구문을 가지고 있습니다. 그래서 그들이 그것을 바꾸고 다르게 만들었을 때, 적어도 그들은 우리 프로그래머들에게 더 좋게 만들었습니다.

그리고 ObjectiveC가 있습니다. C에 몇 가지 개선 사항을 추가했지만 자체 인터페이스 구문, 메서드 호출, 매개 변수 전달 등을 개발했습니다. 나는 왜 그들이 +와-를 바꾸지 않았는지 궁금합니다. 그래서 더하기는 두 개의 숫자를 뺍니다. 더 시원했을 것입니다.

Steve Jobs는 ObjectiveC를 지원함으로써 망쳤습니다. 물론 그는 더 나은 C #을 지원할 수 없지만 최악의 경쟁자에 속합니다. 따라서 이것은 실제적인 것이 아니라 정치적 결정입니다. 기술은 정치적 이유로 기술 결정을 내릴 때 항상 어려움을 겪습니다. 그는 자신이 잘하는 회사를 이끌고 프로그래밍 문제는 실제 전문가에게 맡겨야합니다.

그가 iOS를 작성하고 ObjectiveC 이외의 다른 언어로 라이브러리를 지원하기로 결정했다면 더 많은 iPhone 용 앱이있을 것이라고 확신합니다. 열렬한 팬, 버진 프로그래머 및 스티브 잡스를 제외한 모든 사람에게 ObjectiveC는 우스꽝스럽고 추하고 혐오스러운 것처럼 보입니다.


답변

Objective-c에 대해 제가 좋아하는 한 가지는 객체 시스템이 메시지를 기반으로한다는 것입니다. C #에서는 할 수 없었던 정말 멋진 일을 할 수 있습니다 (적어도 동적 키워드를 지원할 때까지는 불가능합니다!).

코코아 앱 작성의 또 다른 좋은 점은 Interface Builder입니다. Visual Studio의 양식 디자이너보다 훨씬 좋습니다.

(C # 개발자로서) 저를 괴롭히는 obj-c에 대한 점은 자신의 메모리를 관리해야한다는 사실입니다 (가비지 수집이 있지만 iPhone에서는 작동하지 않음). 선택기 구문 및 모든 [].


답변

iPhone 용 Objective-C를 막 시작한 프로그래머로서 C # 4.0에서 왔기 때문에 람다 식, 특히 Linq-to-XML이 누락되었습니다. 람다 식은 C #에 고유 한 반면 Linq-to-XML은 실제로 .NET 대 Cocoa 대비에 가깝습니다. 내가 작성하고있는 샘플 앱에서 문자열에 XML이 있습니다. 나는 그 XML의 요소를 객체 컬렉션으로 파싱하고 싶었다.

Objective-C / Cocoa에서이를 수행하기 위해 NSXmlParser 클래스 를 사용해야했습니다 . 이 클래스 는 요소 열기 태그를 읽을 때, 일부 데이터를 읽을 때 (일반적으로 요소 내부), 일부 요소 끝 태그를 읽을 때 호출되는 (읽기 : 메시지 전송) 메서드를 사용 하여 NSXMLParserDelegate 프로토콜 을 구현하는 다른 개체에 의존합니다 . . 구문 분석 상태와 상태를 추적해야합니다. 그리고 저는 솔직히 XML이 유효하지 않으면 어떻게되는지 전혀 모릅니다. 세부 사항을 파악하고 성능을 최적화하는 데는 좋지만 오 이런, 코드가 너무 많습니다.

대조적으로 다음은 C #의 코드입니다.

using System.Linq.Xml;
XDocument doc = XDocument.Load(xmlString);
IEnumerable<MyCustomObject> objects = doc.Descendants().Select(
         d => new MyCustomObject{ Name = d.Value});

이것으로 XML에서 가져온 사용자 지정 개체 컬렉션이 있습니다. 해당 요소를 값별로 필터링하거나 특정 속성을 포함하는 요소로만 필터링하거나 처음 5 개만 원하거나 처음 1 개를 건너 뛰고 다음 3 개를 가져 오거나 어떤 요소가 반환되었는지 확인하려는 경우 … BAM, 모두 같은 코드 줄에 있습니다.

Objective-C에서이 처리를 훨씬 쉽게 만드는 많은 오픈 소스 클래스가 있으므로 많은 작업을 수행합니다. 이것은 내장 된 것이 아닙니다.

* 참고 : 위의 코드를 실제로 컴파일 한 것이 아니라 C #에서 요구하는 상대적인 상세도가 부족함을 설명하기위한 예제 일뿐입니다.