Избавьтесь от “'NSObject', может не ответить на '-someMethod'” предупреждение

Я обнаружил, что в Java 1.6.0_32 нормальный метод для симпатичной печати строки XML (с использованием Transformer с нулевым или тождественным xslt) не ведет себя так, как я например, если теги просто разделены пробелами, в отличие от отсутствия разделительного текста. Я попытался использовать <xsl:strip-space elements="*"/> в моем шаблоне безрезультатно. Самым простым решением, которое я нашел, было освободить пространство так, как я хотел, используя SAXSource и XML-фильтр. Так как мое решение было для регистрации, я также расширил это для работы с неполными фрагментами XML. Обратите внимание, что обычный метод работает нормально, если вы используете DOMSource, но я не хотел использовать его из-за неполноты и нехватки памяти.

public static class WhitespaceIgnoreFilter extends XMLFilterImpl
{

    @Override
    public void ignorableWhitespace(char[] arg0,
                                    int arg1,
                                    int arg2) throws SAXException
    {
        //Ignore it then...
    }

    @Override
    public void characters( char[] ch,
                            int start,
                            int length) throws SAXException
    {
        if (!new String(ch, start, length).trim().equals("")) 
               super.characters(ch, start, length); 
    }
}

public static String prettyXML(String logMsg, boolean allowBadlyFormedFragments) throws SAXException, IOException, TransformerException
    {
        TransformerFactory transFactory = TransformerFactory.newInstance();
        transFactory.setAttribute("indent-number", new Integer(2));
        Transformer transformer = transFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
        StringWriter out = new StringWriter();
        XMLReader masterParser = SAXHelper.getSAXParser(true);
        XMLFilter parser = new WhitespaceIgnoreFilter();
        parser.setParent(masterParser);

        if(allowBadlyFormedFragments)
        {
            transformer.setErrorListener(new ErrorListener()
            {
                @Override
                public void warning(TransformerException exception) throws TransformerException
                {
                }

                @Override
                public void fatalError(TransformerException exception) throws TransformerException
                {
                }

                @Override
                public void error(TransformerException exception) throws TransformerException
                {
                }
            });
        }

        try
        {
            transformer.transform(new SAXSource(parser, new InputSource(new StringReader(logMsg))), new StreamResult(out));
        }
        catch (TransformerException e)
        {
            if(e.getCause() != null && e.getCause() instanceof SAXParseException)
            {
                if(!allowBadlyFormedFragments || !"XML document structures must start and end within the same entity.".equals(e.getCause().getMessage()))
                {
                    throw e;
                }
            }
            else
            {
                throw e;
            }
        }
        out.flush();
        return out.toString();
    }
10
задан Tyson 8 July 2009 в 03:00
поделиться

3 ответа

Вы также можете использовать id , который является объектом любого типа.

for (id element in myArray) {
    if ([element respondsToSelector:lowercaseSelector]) {
        NSLog([element lowercaseString]);
    }
}
16
ответ дан 3 December 2019 в 15:52
поделиться

Как насчет использования performSelector: ?

SEL lowercaseSelector = @selector(lowercaseString);

for (NSObject *element in myArray) {
    if ([element respondsToSelector:lowercaseSelector]) {
        NSLog([element performSelector:lowercaseSelector]); // No warning
    }
}

Это позволит избавиться от предупреждения компилятора.

6
ответ дан 3 December 2019 в 15:52
поделиться

Просто передайте свой NSObject в NSString перед вызовом функции:

for (NSObject *element in myArray) {
    if ([element respondsToSelector:lowercaseSelector]) {
        NSLog([(NSString*)element lowercaseString]); // No warning!
    }
}
4
ответ дан 3 December 2019 в 15:52
поделиться