2016-08-18 1 views
0

나는 다음과 같은 코드가 있습니다클래스가 NSArray가 아니라 __NSArrayI 인 반면 NSArray의 인스턴스를 만들었습니까?

2016-08-18 21:08:53.628 TestUse[9279:939745] anArrayClass - __NSArrayI 
2016-08-18 21:08:53.629 TestUse[9279:939745] NSArrayClass - NSArray 

가 그럼 난 CAJTestClass라는 테스트 클래스를 생성하고 인스턴스를 생성 :

id anArray = [NSArray arrayWithObjects:@1, @2, nil]; 
NSLog(@"anArrayClass - %@", [anArray class]); 
NSLog(@"NSArrayClass - %@", [NSArray class]); 

을 내가 모두 출력 NSArray 있습니다 기대, 그러나 출력은 밝혀 그 클래스 :

id testInstance = [CAJTestClass new]; 
NSLog(@"testInstanceClass - %@", [testInstance class]); 
NSLog(@"cajTestClass - %@", [CAJTestClass class]); 

이번에 출력된다 :

,
2016-08-18 21:08:53.629 TestUse[9279:939745] testInstanceClass - CAJTestClass 
2016-08-18 21:08:53.629 TestUse[9279:939745] cajTestClass - CAJTestClass 

이번에는 내가 예상 한 결과입니다. 그러나 일 수있는 이유는 무엇입니까?
"Effective Objective-C"에 대한 설명은 NSArray이 "클래스 클러스터"의 일부분이라는 것입니다.이 클래스는 상속 관계가있는 일련의 클래스입니다. 그러나 CAJTestClassNSObject의 하위 클래스이기도합니다. 내가 잘못?

편집 : 답장을 보내 주셔서 감사합니다. 그러나 "클래스 클러스터"의 업무에 기여해야한다면이 두 가지 사례에서 다른 결과가 나오는 이유는 무엇입니까?

답변

3

편집을 사용할 수 있습니다. 그러나 "클래스 클러스터"의 업무에 기여해야한다면이 두 가지 사례에서 다른 결과가 나오는 이유는 무엇입니까?

테스트 코드가 완전히 다르기 때문에. NSArray 메서드를 호출하여 NSArray 하위 클래스를 반환하지만 [CAJTestClass new]을 호출하면 CAJTestClass이 반환됩니다.

id testInstance = [CAJTestClass testClassWithMagic]; 
    NSLog(@"testInstanceClass - %@", [testInstance class]); 
    NSLog(@"cajTestClass - %@", [CAJTestClass class]); 

2016-08-18 09:57:15.126 test[72004:47882338] testInstanceClass - __MagicTestSubclass 
2016-08-18 09:57:15.127 test[72004:47882338] cajTestClass - CAJTestClass 

rmaddy 당신이 다른 질문 그는이 가능성을 제기 : 이제 테스트 코드를 사용하여

@interface CAJTestClass : NSObject 
+ (instancetype)testClassWithMagic; 
@end 

@interface __MagicTestSubclass : CAJTestClass 
@end 

@implementation CAJTestClass 

+ (instancetype)testClassWithMagic { 
    return [__MagicTestSubclass new]; 
} 
@end 

@implementation __MagicTestSubclass 
@end 

: 당신이 그들을 동일을 할 수 있도록 경우에, 당신은 동일한 결과를 얻을 수 맞을지도 모릅니다. 그래서 나는 그 대답에 대해서도 대답 할 것입니다.

[anArray class]-class 메시지를 anArray 인스턴스로 전달한 결과입니다. -class 메시지를 수신 할 때 인스턴스가 수행하는 일반적인 작업은 초기화 된 특정 클래스 (특정 서브 클래스)를 반환하는 것입니다. 이는 보편적이지 않습니다 (KVO 클래스는 의도적으로이 규칙을 위반하며 런타임에 클래스를 변경할 수도 있습니다). 그러나 이는 일반적인 접근 방법입니다. 디스패처에게 사용할 메소드 집합을 알려주는 구조체의 isa 포인터입니다. 따라서 실제로 인스턴스화 된 클래스 객체 (__NSArrayI)를 얻습니다.

[NSArray class]+class 메시지를 클래스 개체 NSArray에 전달한 결과입니다. 클래스 객체에 대한 일반적인 사항은 return self입니다 (해당 규칙을 위반하는 클래스는 알지 못하므로 해당 규칙을 위반하는 것은 합당하지 않을 수 있음). 따라서 메시지를 전달한 수업을 받게됩니다 (NSArray).

+0

OP는 왜 [anArray class]와 [NSArray class]가 다른 결과를 반환하는지 알고 싶어합니다. – rmaddy

+0

그것이 원래의 질문이었습니다. (다른 답변에서도 잘 대답했습니다.) 그러나 편집은 NSArray에 대한 한 가지 이유가 무엇인지에 대한 질문 이었지만 CAJTestClass에 대한 또 다른 방법이었습니다. 이유는'CAJTestClass' 케이스가'NSArray'와 완전히 다른 코드이기 때문입니다. –

+0

아니요, 두 답변이 서로 다른 이유를 설명하는 답은 없습니다. 그것은 모두'__NSArrayI'가 무엇인지 설명합니다. – rmaddy

3

소프트웨어 개발시 걱정할 클래스는 NSArray 및 NSMutableArray뿐입니다. 뒤에는 여러 가지 수업이 있습니다. 예를 들어 빈 배열에 대한 싱글 톤 클래스입니다. 1 개의 배열 요소를 가지는 배열의 클래스입니다. 사람들은 수톤의 하찮은 배열을 사용하기 때문에 All은 메모리를 저장합니다.

+2

나는 "뒷이야기"에 대한 언급과 관련하여이 답변을 별도로 표결했습니다. 요점은'NSArray arrayWithObjects :'는 NSArray 인터페이스를 구현하는 무엇이든지 반환하도록 허용된다는 것입니다. 귀하의 코드는 어떤 클래스를 가져야하는지 특별히 신경 쓰지 않아야합니다. "클래스 클러스터"는 대개 init 또는 factory 메소드에서 얻은 값이 alloc'd 클래스의 유형이거나 팩토리 메소드를 사용할 필요가 없음을 의미합니다. 가장 일반적으로 하위 클래스가됩니다. – Tommy

1

__NSArrayI는 변경할 수없는 "일반"NSArray라는 변경 불가능한 배열의 코드 워드입니다.

__NSArrayM은 변경 가능한 배열, 즉 NSMutableArray의 코드 워드입니다. NSMutableArray에서 항목을 추가하고 제거 할 수 있습니다.

0

__NSArrayI은 초기화 후에 변경 될 수없는 변경 불가능한 어레이 버전을 나타냅니다.

0

__NSArrayI는 NSArray의 변경 불가능한 형식을 의미합니다. 그리고 __NSArrayM도 있습니다.이 형식은 변경 가능한 형식입니다. 변경할 수 없다는 것이 변경 불가능하다는 것은이 배열 안의 객체를 변경할 수 없다는 것을 의미합니다. 그리고 가변적 인 경우 요소를 변경할 수 있습니다. U 또한이 게시물을 확인할 수 있습니다. 나는 이것 또한 당신의 질문에 대답을 생각합니다. What is __NSArrayI and __NSArrayM? How to convert to NSArray?

1

__NSArrayI은 변경 불가능한 개인용 클래스 NSArray입니다. 또한 가변 배열의 개인 클래스 인 __NSArrayM이 있습니다. 모두

+ arrayWithObjects:이 당신이 앱 스토어 배포를 위해 사용할 수 없습니다 개인 API는 당신이 그것에 대해 아무것도 할 수가없는 __NSArrayI 반환 NSArray의 서브 클래스입니다. 모든 답변을 주셔서 감사합니다 : 당신이 당신의 객체가 NSArray 있는지 확인하려면

당신은

if ([anArray isKindOfClass:[NSArray class]]){ 
    //blablabla 
} 
관련 문제