objective c - objective - NSMutableArray-배열에 특정 객체 유형 만 보유하도록합니다.



objective-c cocoa (8)

하나의 특정 객체 유형 만 보유하도록 NSMutableArray를 강제하는 방법이 있습니까?

다음과 같이 클래스 정의가 있습니다.

@interface Wheel:NSObject  
{    
  int size;  
  float diameter;  
}  
@end  


@interface Car:NSObject  
{  
   NSString *model;  
   NSString *make;  
   NSMutableArray *wheels;  
}  
@end

배열이 코드로만 Wheel 객체를 유지하도록하려면 어떻게해야합니까? (그리고 절대적으로 다른 객체들)

https://ffff65535.com


NSMutableArray를 하위 클래스 화하지 않도록하기 위해 수행 한 작업은 다음과 같습니다. 이렇게하면 원하는 인수와 반환 유형을 가질 수 있습니다. 명명 규칙에 유의하십시오. 사용할 각 메소드에서 "object"라는 단어를 요소 클래스의 이름으로 바꿉니다. "objectAtIndex"는 "wheelAtIndex"가됩니다. 이렇게하면 이름 충돌이 발생하지 않습니다. 아주 깔끔하다.

typedef NSMutableArray WheelList;
@interface NSMutableArray (WheelList) 
- (wheel *) wheelAtIndex: (NSUInteger) index;
- (void) addWheel: (wheel *) w;
@end

@implementation NSMutableArray (WheelList)

- (wheel *) wheelAtIndex: (NSUInteger) index 
{  
    return (wheel *) [self objectAtIndex: index];  
}

- (void) addWheel: (wheel *) w 
{  
    [self addObject: w];  
} 
@end


@interface Car : NSObject
@property WheelList *wheels;
@end;


@implementation Car
@synthesize wheels;

- (id) init 
{
    if (self = [super init]) {
        wheels = [[WheelList alloc] initWithCapacity: 4];
    }
    return self;
}

@end

XCode 7을 사용하여 Objective-C에서 제네릭을 사용할 수 있습니다!

따라서 NSMutableArray 를 다음과 같이 선언 할 수 있습니다.

NSMutableArray <Wheel*> *wheels = [[NSMutableArray alloc] initWithArray:@[[Wheel new],[Wheel new]];

배열에 휠이 아닌 객체를 넣으려고하면 컴파일러에서 경고를 표시합니다.


그건 불가능하다; NSArray (변경 가능 여부와 상관 없음)는 모든 객체 유형을 보유합니다. Jim이 이미 제안한대로 사용자 정의 하위 클래스를 만드는 것이 좋습니다. 또는 배열을 필터링하여 원하는 유형이 아닌 객체를 제거하려는 경우 다음을 수행 할 수 있습니다.

- (void)removeObjectsFromArray:(NSMutableArray *)array otherThanOfType:(Class)type
{
    int c = 0;
    while(c < [array length])
    {
        NSObject *object = [array objectAtIndex:c];
        if([object isKindOfClass:type])
          c++;
        else
          [array removeObjectAtIndex:c];
    }
}

...
[self removeObjectsFromArray:array otherThanOfType:[Car class]];

또는 isKindOfClass :의 결과를 기반으로 다른 판단을 내리면, 예를 들어 Cars와 Wheels의 혼합을 포함하는 배열을 두 개의 배열로 나눌 수 있습니다. 각 배열에는 각각 한 종류의 객체 만 들어 있습니다.


나는 이것이 도움이되기를 바란다 (그리고 일하기 ... : P)

Wheel.h 파일 :

@protocol Wheel
@end

@interface Wheel : NSObject
@property ...
@end

Car.h 파일 :

#import "Wheel.h"
@interface Car:NSObject  

{  
   NSString *model;  
   NSString *make;  
   NSMutableArray<Wheel, Optional> *wheels;  
}  
@end

Car.m 파일 :

#import "Car.h"
@implementation Car

-(id)init{
   if (self=[super init]){
   self.wheels = (NSMutableArray<Wheel,Optional>*)[NSMutableArray alloc]init];
   }
return self;
}
@end

내가 아는 한 .. 바퀴에 mutableArray 개체를 추가하기 전에 몇 가지 확인 표시를 추가해야합니다. 내가 추가하는 객체가 클래스 "휠"입니까? 그것이 추가되면 다른 현명한 없습니다.

예:

if([id isClassOf:"Wheel"] == YES)
{
[array addObject:id) 
}

이 같은. 나는 정확한 구문을 기억하지 못한다.


이것을 허용하는 하나의 헤더 파일 프로젝트가 있습니다 : Objective-C-Generics

사용법 :

ObjectiveCGenerics.h를 프로젝트에 복사하십시오. 새 클래스를 정의 할 때는 GENERICSABLE 매크로를 사용하십시오.

#import "ObjectiveCGenerics.h"

GENERICSABLE(MyClass)

@interface MyClass : NSObject<MyClass>

@property (nonatomic, strong) NSString* name;

@end

이제 Java, C # 등에서 일반적으로하는 것처럼 배열 및 세트와 함께 제네릭을 사용할 수 있습니다.

암호:


프로토콜 아마도 좋은 생각 :

@protocol Person <NSObject>
@end

@interface Person : NSObject <Person>
@end

사용:

NSArray<Person>*  personArray;

NSMutableArray 그대로 사용하는 방법이 없다고 생각합니다. 당신은 아마 모든 생성자와 삽입 메소드를 서브 클래스 화하고 오버 라이딩함으로써이를 강제 할 수 있지만, 아마도 그만한 가치는 없을 것입니다. 이것으로 무엇을 달성하기를 희망하십니까?





nsmutablearray