2014-12-22 2 views
2

У меня есть объект NSValue, который может «вставить» экземпляр неизвестного типа (CGPoint, CGRect и т. Д.), И мне нужно определить этот тип во время выполнения. Как мне это сделать в Свифт?Как узнать тип объекта, помещенного в NSValue с помощью Swift?

Я пытался сделать что-то вроде этого:

if ((value as Any) is CGPoint) {} 
else if (((value as Any) is CGRect)) {} 
... 

Когда value является объектом NSValue, содержащий CGPoint, не попасть в, если п. Тогда я, когда печатал value, дает мне NSPoint: {150, 150}, который, как я полагаю, почему-то не попадает в статью.

Любые идеи, почему это происходит и как его решить?

Большое спасибо!

+0

Там есть бесплатный шунтирующий между NS * и * CG. Вы пытались использовать NSPoint вместо CGPoint в предложении if? Например. 'if value is NSPoint {' –

+0

Я пробовал это, но компилятор не принимает это сравнение, и я получаю сообщение об ошибке «Использование необъявленного типа NSPoint» –

ответ

2

Ah, NSValue, вы так сумасшедшие. Несмотря на то, что NSRect и т. Д. Не должны быть на iOS, если вы положили CGRect внутри NSValue, внутри он отображает, что внутри него находится NSRect.

Во всяком случае, в то время как они служат аналогичные цели, я не думаю, что вы можете использовать Any для преобразования NSValue или из CGPoint или CGRect. Вы должны позвонить value.CGRectValue() и т. Д. Но, к вашему моменту, вам нужно знать, что это такое. Что же не так легко, но вы можете сделать это:

let type = String.fromCString(val.objCType) ?? "" 
if type.hasPrefix("{CGRect") { 
    let rect = val.CGRectValue() 
} 
else if type.hasPrefix("{CGPoint") { 
    let point = val.CGPointValue() 
} //etc... 

Но другой вопрос будет, действительно ли вы должны использовать NSValue? Это своего рода обходное решение Obj-C. Дается ли вам то, что вы не можете изменить, или, может быть, вам лучше использовать Any (или даже лучше, дженерики)?

+0

Это хороший момент, но я хочу моделировать поведение CAKeyFrameAnimation, которое имеет свойство «значения» типа [AnyObject]! Но в любом случае, спасибо за ваше решение. Это будет работать. –

1

Для начала, iOS не использует NSPoint, так что это будет потеря. Мое лучшее предположение для чего-то вроде этого было бы вернуться к использованию objCType, как это будет обрабатываться в объективе-C. К сожалению, у вас нет доступа к @encode с быстрым, так что вы завершаете необходимости прописывать возможности:

switch String(CString: value.objCType, encoding: NSUTF8StringEncoding) { 
case "{CGPoint=dd}": // handle CGPoint here 
case "{CGRect={CGPoint=dd}{CGSize=dd}}": // handle CGRect here 
} 
Смежные вопросы