クラス ID のオブジェクト myObject がある場合、それを CGPoint として「キャスト」するにはどうすればよいでしょうか (イントロスペクションを実行し、myObject を CGPoint に認識しているとします)。これは、CGPoint が実際の Obj-C クラスではないにもかかわらずです。
単純に実行(CGPoint)myObject
すると、次のエラーが返されます。
Used type 'CGPoint' (aka 'struct CGPoint') where arithmetic or pointer type is required
これを実行して、NSMutableArray に渡されるオブジェクトが CGPoint であるかどうかを確認し、そうである場合は CGPoint を NSValue に自動的にラップします。例えば:
- (void)addObjectToNewMutableArray:(id)object
{
NSMutableArray *myArray = [[NSMutableArray alloc] init];
id objectToAdd = object;
if ([object isKindOfClass:[CGPoint class]]) // pseudo-code, doesn't work
{
objectToAdd = [NSValue valueWithCGPoint:object];
}
[myArray addObject:objectToAdd];
return myArray;
}
追加コード
「イントロスペクション」を実行するために使用する関数は次のとおりです。
+ (BOOL)validateObject:(id)object
{
if (object)
{
if ([object isKindOfClass:[NSValue class]])
{
NSValue *value = (NSValue *)object;
if (CGPointEqualToPoint([value CGPointValue], [value CGPointValue]))
{
return YES;
}
else
{
NSLog(@"[TEST] Invalid object: object is not CGPoint");
return NO;
}
}
else
{
NSLog(@"[TEST] Invalid object: class not allowed (%@)", [object class]);
return NO;
}
}
return YES;
}
+ (BOOL)validateArray:(NSArray *)array
{
for (id object in array)
{
if (object)
{
if ([object isKindOfClass:[NSValue class]])
{
NSValue *value = (NSValue *)object;
if (!(CGPointEqualToPoint([value CGPointValue], [value CGPointValue])))
{
NSLog(@"[TEST] Invalid object: object is not CGPoint");
return NO;
}
}
else
{
NSLog(@"[TEST] Invalid object: class not allowed (%@)", [object class]);
return NO;
}
}
}
return YES;
}
+ (NSValue *)convertObject:(CGPoint)object
{
return [NSValue valueWithCGPoint:object];
}