목표-C에 강력한 유형의 컬렉션이 있습니까?
저는 맥/아이폰 프로그래밍과 오브젝티브-C에 익숙하지 않습니다.C#과 Java에는 선언된 유형의 멤버만 될 수 있는 컬렉션 클래스인 "generics"가 있습니다.예를 들어, C#에서
Dictionary<int, MyCustomObject>
정수 키와 MyCustomObject 유형의 값만 포함할 수 있습니다.목표-C에도 유사한 메커니즘이 존재합니까?
애플은 Xcode 7에서 오브젝티브-C에 '경량 제네릭'을 도입했습니다.Objective-C에서 유형 불일치가 있는 경우 컴파일러 경고를 생성합니다.
NSArray<NSString*>* arr = @[@"str"];
NSString* string = [arr objectAtIndex:0];
NSNumber* number = [arr objectAtIndex:0]; // Warning: Incompatible pointer types initializing 'NSNumber *' with an expression of type 'NSString *'
스위프트 코드에서는 컴파일러 오류가 발생합니다.
var str: String = arr[0]
var num: Int = arr[0] //Error 'String' is not convertible to 'Int'
Lightweight Generics는 NSRray, NSDictionary 및 NSSet와 함께 사용하도록 설계되었지만, 자신의 클래스에 추가할 수도 있습니다.
@interface GenericsTest<__covariant T> : NSObject
-(void)genericMethod:(T)object;
@end
@implementation GenericsTest
-(void)genericMethod:(id)object {}
@end
목표-C는 컴파일러 경고와 함께 이전과 같이 동작합니다.
GenericsTest<NSString*>* test = [GenericsTest new];
[test genericMethod:@"string"];
[test genericMethod:@1]; // Warning: Incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'
그러나 Swift는 Generic 정보를 완전히 무시합니다. (Swift 3+에서는 더 이상 사실이 아닙니다.)
var test = GenericsTest<String>() //Error: Cannot specialize non-generic type 'GenericsTest'
이러한 Foundation 컬렉션 클래스 외에도 Objective-C Lightweight 제네릭은 Swift에 의해 무시됩니다.Lightweight 제네릭을 사용하는 다른 유형은 매개 변수가 없는 것처럼 Swift로 가져옵니다.
이 대답은 구식이지만 역사적 가치를 위해 남아 있습니다.Xcode 7 기준으로, 2015년 6월 8일 코너의 답변이 더 정확합니다.
아니요, 사용자 지정 컬렉션 클래스에서 C++ 템플릿을 사용하지 않는 한 목표-C에는 제네릭이 없습니다.
Objective-C는 동적 타이핑을 특징으로 하며, 이는 모든 객체가 메시지를 수신할 수 있기 때문에 런타임이 객체의 유형에 관심이 없다는 것을 의미합니다.기본 제공 컬렉션에 개체를 추가하면 개체가 유형인 것처럼 처리됩니다.id
그러나 일반적인 개체에 메시지를 보내면 됩니다. 물론 컬렉션의 하나 이상의 개체가 보내는 메시지에 응답하지 않는 한 정상적으로 작동합니다.
제네릭은 강력하고 정적인 유형의 언어이기 때문에 Java 및 C#과 같은 언어에서 필요합니다.오브젝티브-C의 동적 타이핑 기능과는 전혀 다른 구기 종목.
아니요, 하지만 저장할 개체 유형에 대해 설명할 수 있습니다. 요즘 Java 1.4로 무언가를 작성해야 할 때 이 작업을 몇 번 본 적이 있습니다. 예:
NSMutableArray* /*<TypeA>*/ arrayName = ....
또는
NSDictionary* /*<TypeA, TypeB>*/ dictionaryName = ...
목표 C 코드에서는 컴파일 시간 검사일 뿐이며, 잘못된 형식을 컬렉션에 넣거나 입력된 속성에 할당할 때만 런타임 오류가 발생하지 않습니다.
선언:
@interface FooClass <T> : NSObject
@property (nonatomic) T prop;
@end
사용:
FooClass<NSString *> *foo = [[FooClass alloc] init];
NSArray<FooClass<NSString *> *> *fooAry = [NSArray array];
하세요.*
s의
목표-C에는 제네릭이 없습니다.
배열은 개체의 순서가 지정된 집합입니다.코코아는 여러 어레이 클래스, NSArray, NSMutableArray(NSArray의 하위 클래스) 및 NSPointerArray를 제공합니다.
Apple은 XCode 7에서 ObjC에 제네릭을 추가했습니다.
@property NSArray<NSDate *>* dates;
- (NSArray<NSDate *> *)datesBeforeDate:(NSDate *)date;
- (void)addDatesParsedFromTimestamps:(NSArray<NSString *> *)timestamps;
여기를 참조하십시오. https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html #//apple_ref/doc/uid/TP40014216-CH6-ID61
일반적인 NSA 레이는 하위 분류를 통해 실현할 수 있습니다.NSArray
제공된 모든 방법을 보다 제한적인 방법으로 재정의합니다.를 들면, 들면를예,
- (id)objectAtIndex:(NSUInteger)index
에서 재정의해야 합니다.
@interface NSStringArray : NSArray
~하듯이
- (NSString *)objectAtIndex:(NSUInteger)index
NSA ray에 NSS 문자열만 포함할 수 있습니다.
생성된 하위 클래스는 드롭인 대체로 사용할 수 있으며 컴파일러 경고, 속성 액세스, 향상된 코드 생성 및 Xcode의 -complete와 같은 많은 유용한 기능을 제공합니다.이 모든 기능은 컴파일 타임 기능이므로 실제 구현을 재정의할 필요가 없습니다. NSArray의 방법은 여전히 사용될 수 있습니다.
이를 자동화하여 두 개의 문으로 요약할 수 있으므로 제네릭을 지원하는 언어에 가깝습니다.저는 WMGeneric Collection으로 자동화를 만들었습니다. 여기서 템플릿은 C 프리프로세서 매크로로 제공됩니다.
매크로가 포함된 헤더 파일을 가져온 후에는 인터페이스용과 구현용 두 개의 문으로 일반 NSArray를 생성할 수 있습니다.저장할 데이터 유형과 하위 클래스의 이름만 제공하면 됩니다.은 WMGeneric Collection의 합니다.NSArray
,NSDictionary
그리고.NSSet
그들의 가변적인 상대들뿐만 아니라.
예:List<int>
라고 불리는 사용자 정의 클래스에 의해 실현될 수 있습니다.NumberArray
다음 문으로 생성됩니다.
WMGENERICARRAY_INTERFACE(NSNumber *, // type of the value class
// generated class names
NumberArray, MutableNumberArray)
를 후NumberArray
프로젝트의 모든 곳에서 사용할 수 있습니다.은 이부다니족합의 합니다.<int>
그러나 이름 지정 체계를 선택하여 클래스를 템플리트로 레이블을 지정할 수 있습니다.
다음을 살펴보십시오.
https://github.com/tomersh/Objective-C-Generics
프로토콜 검사 메커니즘을 변경함으로써 일종의 가난한 사람들의 제네릭으로 보입니다.
이제 꿈이 실현됩니다. 오늘부터 오브젝티브-C에는 제네릭이 있습니다(WWDC 감사합니다).농담이 아닙니다 - Swift의 공식 페이지에서:
새로운 구문 기능을 통해 언어 간의 일관성을 향상시키면서 보다 표현력 있는 코드를 작성할 수 있습니다.SDK는 제네릭 및 nullability 주석과 같은 새로운 Objective-C 기능을 사용하여 Swift 코드를 더욱 깨끗하고 안전하게 만들었습니다.다음은 Swift 2.0 향상된 기능의 샘플입니다.
그리고 이를 증명하는 이미지:
그냥 여기로 뛰어들고 싶어요.저는 여기에 제네릭에 대한 블로그 게시물을 작성했습니다.
제가 기여하고 싶은 것은 애플이 나타내는 것처럼 수집 클래스뿐만 아니라 제네릭을 어떤 클래스에도 추가할 수 있다는 것입니다.
저는 애플의 컬렉션과 정확히 동일하게 작동하기 때문에 다양한 클래스에 성공적으로 추가했습니다. 즉, 컴파일 시간 확인, 코드 완료, 캐스트 제거 활성화 등입니다.
즐거운 시간 되세요.
Apple 및 GNUStep 프레임워크에서 제공하는 Collections 클래스는 정렬 가능한 개체와 특정 메시지에 응답하는 개체가 주어졌다고 가정한다는 점에서 반일반적입니다.플로트, int 등과 같은 원시 요소의 경우 모든 C 배열 구조가 손상되지 않고 사용할 수 있으며 일반 컬렉션 클래스(예: NSNumber)에서 사용할 수 있는 특수 래퍼 개체가 있습니다.또한 컬렉션 클래스는 모든 유형의 개체를 허용하도록 하위 분류(또는 범주를 통해 구체적으로 수정)될 수 있지만 모든 유형 처리 코드를 직접 작성해야 합니다.메시지는 모든 개체로 전송될 수 있지만 개체에 적합하지 않거나 메시지를 적절한 개체로 전달해야 하는 경우 null을 반환해야 합니다.실제 형식 오류는 런타임이 아닌 컴파일 시간에 탐지되어야 합니다.런타임에 이러한 파일을 처리하거나 무시해야 합니다.마지막으로 Objc는 까다로운 사례를 처리할 수 있는 런타임 반영 기능을 제공하며, 메시지를 보내거나 부적절한 컬렉션에 넣기 전에 객체에 대한 메시지 응답, 특정 유형 및 서비스를 확인할 수 있습니다.서로 다른 라이브러리와 프레임워크는 코드 응답이 없는 메시지를 보낼 때 개체가 어떻게 동작하는지에 대해 서로 다른 규칙을 채택합니다. 즉, RTFM입니다.장난감 프로그램과 디버깅 빌드를 제외하고, 대부분의 프로그램은 정말로 실수하여 메모리나 디스크에 잘못된 데이터를 쓰거나, 불법 작업을 수행하거나(예: 0으로 나눕니다. 하지만 그것도 잡을 수 있습니다), 시스템 리소스에 액세스할 수 없는 경우를 제외하고는 충돌할 필요가 없습니다.Objective-C의 역동성과 런타임은 모든 것이 정상적으로 실패할 수 있도록 하며 코드에 내장되어야 합니다.(HINT) 기능의 일반성에 문제가 있는 경우 구체성을 시험해 보십시오.함수를 특정 유형으로 덮어쓰고 런타임이 런타임에 적절한 멤버 함수를 선택하도록 합니다.
Example:
-(id) sort (id) obj; // too generic. catches all.
// better
-(id) sort: (EasilySortableCollection*) esc;
-(id) sort: (HardToSortCollection*) hsc;
...
[Sorter sort: MyEasyColl];
[Sorter sort: MyHardColl];
언급URL : https://stackoverflow.com/questions/848641/are-there-strongly-typed-collections-in-objective-c
'sourcecode' 카테고리의 다른 글
당월을 어떻게 받을 수 있습니까? (0) | 2023.06.18 |
---|---|
다음/이전 단추를 클릭하여 진행률 표시줄 전환 (0) | 2023.06.13 |
디렉터리 검색기에서 1000개 이상의 레코드를 가져올 수 있습니까? (0) | 2023.06.13 |
IIS에서 Windows 인증이 웹 응용 프로그램의 옵션 중 하나로 표시되지 않는 이유는 무엇입니까? (0) | 2023.06.13 |
JDBC 연결 기본 자동 커밋 동작 (0) | 2023.06.13 |