3

나는 objective-C 게임을 작성하고 있으며 게임 루프에서 일부 코드를 최적화해야하는 단계에 있습니다.
내가문자열 비교 대 목표 -C에서 클래스 비교

경우, 클래스의 광대 한 양이 사용되는 방법을 비교하게 ([isMemberOfClass OBJ : [SomeClass 클래스]])

등 내가 검사의 종류를 듣고
은 매우 비싸다 왜냐하면 하나의 배열에 여러 클래스가 채워져 있기만하기 때문에 어떤 종류의 클래스 검사가 필요합니다.
문자열 속성을 포함하기 위해 NSObject를 서브 클래 싱하는 NSObject에 속성을 추가한다고 생각했을 것입니다. 초기화 중에는 해당 하위 클래스의 클래스 이름과 같게됩니다. 그리고 단순히 만약

하고 ([isEqualTo obj.klass을 "SomeClass"@])

이 도움이 될 것인가?
가능한 한 게임 루프에서 최대한 많은 동적 코딩을 유지하려고합니다.

감사합니다.

+1

isMemberOfClass 또는 isKindOfClass가 특히 비싼 이유를 모르겠습니다. 그러나 클래스에서 필드를 구분할 경우 int/NSNumber 필드를 사용하여 switch 문에서 값을 사용할 수 있습니다. –

+0

클래스는 C가 아니라 K ... 그리고 객체 클래스의 문자열을 원한다면 NSStringFromClass() 함수를 사용해야합니다 ... – Macmade

+1

@property (assign)를 정의 할 수 없습니다. NSString *수업. 무엇이든을 위해 "종류"를 사용하는 것은 그것의 보류 한 상표로 금지된다. Im은 문자열 비교를 사용하여 얻을 수있는 이점이 있는지 묻습니다. NSStringFromClass() 메소드는 init 메소드에 위치 할 것이고 반복 루프에서 호출되지 않을 것이다. – Ospho

답변

10

짧은 대답 : 아니오. 문자열 비교는 개체를 비교하는 (또는 : 분류, 분류하는) 다른 방법에 비해 엄청나게 비쌉니다.

긴 대답 : 분석하고 측정하고 비교하지 않은 것을 최적화하지 마십시오. 최적화를 시작하기 전에 정말로 원하는 것은 앱의 작동 방식과 성능 병목 현상을 명확하게 파악하는 것입니다. 시도한 변경으로 인해 성능이 눈에 띄게 변경되지는 않으므로 먼저 실제 병목 현상을 발견하는 것이 좋습니다.

이 특별한 경우 NSString에 isEqual을 보내는 것은 테스트가 실패 할 경우 isMemberOfClass보다 4 배 느립니다. 그리고 이러한 조건부 테스트는 대부분 실패합니다. 따라서 테스트가 성공적으로 수행 된 결과를 무시해야합니다.

문자열 비교가 간단합니다. 포인터 비교가 간단하기 때문에 두 문자열이 같으면 동일한 메모리 주소를 가리킬 가능성이 큽니다. 그것들이 동일하지 않으면 문자열의 각 문자가 해시 메서드를 사용하여 동일성을 비교할 것입니다.

다음은 performance test project에 추가 한 개체 비교 테스트의 결과입니다. 이 프로젝트를 사용하여 추가 테스트를 할 수 있습니다.

enter image description here

2

이 정말 귀하의 질문에 직접 대답이 아니라 넓은 의미의 대답이다.

Objective-C에서 철학은 메시지를 보내고 객체로 하여금 처리 할 작업을 결정하게하는 스몰 토크의 철학과 더 비슷합니다. 객체가 어떤 클래스인지 확인하기 위해 많은 테스트를해야한다는 것을 알게되면 디자인을 재고해야합니다.

for (id anObj in array) 
{ 
    int anInt = [anObj intValue]; 
    // do something with anInt 
} 

그것은 중요하지 않습니다 당신이 객체의 배열을 가지고 있고 그것에 약간의 수학을 할 정수로 각각 변환하려면

는 예를 들어, 당신은 이런 식으로 뭔가를 할 수 각 클래스의 클래스는 anObj이고, -intValue을 보낼 수 있습니다. 예를 들어, 배열이 NSStringsNSNumbers으로 가득 찬 경우, 위의 코드는 예상 한대로 작동합니다.

많은 클래스가 선택기 -intValue의 메소드를 정의하지 않습니다. 예를 들어, 해당 메시지를 NSData의 인스턴스로 보내면 예외를 throw하여 응답합니다. 상황에 따라이 문제를 해결할 수있는 몇 가지 방법이 있습니다.

  1. 개체가이 배열에 넣어 알고 모든 클래스에 대한 선택기를 정의 선택기

    for (id anObj in array) 
    { 
        if ([anObject respondsToSelector: @selector(intValue)]) 
        { 
         int anInt = [anObj intValue]; 
         // do something with anInt 
        } 
    } 
    
  2. 에 대해 알고 있는지 테스트하여 선택에 응답하지 않는 객체를 무시 . 이것은 category을 선언하여 이루어집니다. 이렇게하면 서브 클래 싱없이 Objective-C 클래스를 확장 할 수 있습니다. 예를 들어 길이 나 바이트 또는 다른 적절한 값의 합을 반환하는 NSData의 intValue 메서드를 정의 할 수 있습니다.

  3. protocol을 선언하여 요구 사항을 공식화하십시오. 그런 다음 프로토콜 준수 여부를 테스트하거나 컴파일 시간 검사를 사용하여 배열에 넣은 개체가 프로토콜을 준수하는지 확인할 수 있습니다.

할 수있는 일이 많이 있지만 클래스 계층 구조의 C++/Java 모델에서 조금 벗어나야합니다. Objective-C는 그 점에서 훨씬 더 융통성이 있습니다.

+0

통찰력을 주셔서 감사합니다. objective-C (bar simple C)는 실제로 제가 올바르게 배웠던 첫 번째 언어입니다. – Ospho