Другое событие NullPointerException
возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.
String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals
для гарантированного непустого объекта.
Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null
.
Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.
String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Есть гораздо более простое решение: использовать PlistBuddy , включенный в / usr / libexec / PlistBuddy
в Leopard. См. мой ответ на связанный вопрос SO для подробностей.
PlistBuddy может использоваться на этапе построения сценария выполнения из Xcode и может использоваться только для воздействия на обработанный файл plist. Просто поместите его после фазы копирования ресурсов, и вам даже не нужно очищать цель, чтобы она запускалась каждый раз. Вам даже не нужно выводить значение в файл заголовка и заставлять SVN игнорировать его.
echo -n ${TARGET_BUILD_DIR}/${INFOPLIST_PATH} \
| xargs -0 /usr/libexec/PlistBuddy -c "Set :CFBundleVersion `svnversion -n`"
Предполагая, что вы добавляете этап сборки до того, как произойдет подписание кода, ваш список должен быть подписан с подставленным значением.
Для потомства я сделал что-то подобное zoul для приложений для iPhone, путем добавления revision.h к моему проекту, затем добавления следующего как фазы разработки Сценария Выполнения:
REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`
echo "#define kRevisionNumber @\"$REV\"" > ${PROJECT_DIR}/revision.h
я сделал это для захвата простого числа пересмотра, в противоположность более подробной строке, которую svnversion производит в решении zoul.
Для приложений Mac, я основывал свой подход к это сообщение , и вместо этого создал buildnumber.xcconfig файл. При настройках сборки для цели я изменился На основе значения в нижнем правом углу диалогового окна к buildnumber.xcconfig. В Info.plist я отредактировал следующие строки:
<key>CFBundleVersion</key>
<string>${BUILD_NUMBER}</string>
<key>CFBundleShortVersionString</key>
<string>Version 1.0</string>
Так, чтобы мой О диалоговом окне отобразил бы строку версии, подобную Версии 1.0 (1234), где 1234 является числом пересмотра Подрывной деятельности. Наконец, я создал фазу разработки Сценария Выполнения со следующим кодом:
REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`
echo "BUILD_NUMBER = $REV" > ${PROJECT_DIR}/buildnumber.xcconfig
Это не может быть самым чистым путем, поскольку он требует чистого цикла прежде, чем создать для нового пересмотра для утверждений в приложении, но он работает.
# Xcode auto-versioning script for Subversion
# by Axel Andersson, modified by Daniel Jalkut to add
# "--revision HEAD" to the svn info line, which allows
# the latest revision to always be used.
#
# modified by JM Marino to change only [BUILD] motif
# into CFBundleGetInfoString key.
#
# HOW TO USE IT: just add [BUILD] motif to your Info.plist key :
# CFBundleVersion
#
# EXAMPLE: version 1.3.0 copyright 2003-2009 by JM Marino
# with [BUILD] into CFBundleVersion key
use strict;
die "$0: Must be run from Xcode" unless $ENV{"BUILT_PRODUCTS_DIR"};
# Get the current subversion revision number and use it to set the CFBundleVersion value
#my $REV = `/usr/local/bin/svnversion -n ./`;
my $REV = `/usr/bin/svnversion -n ./`;
my $INFO = "$ENV{BUILT_PRODUCTS_DIR}/$ENV{WRAPPER_NAME}/Contents/Info.plist";
my $version = $REV;
# (Match the last group of digits without optional letter M | S):
($version =~ m/(\d+)[MS]*$/) && ($version = "" . $1);
die "$0: No Subversion revision found" unless $version;
open(FH, "$INFO") or die "$0: $INFO: $!";
my $info = join("", <FH>);
close(FH);
#$info =~ s/([\t ]+<key>CFBundleVersion<\/key>\n[\t ]+<string>.+)\[BUILD\](<\/string>)/$1$version$2/;
$info =~ s/([\t ]+<key>CFBundleVersion<\/key>\n[\t ]+<string>)\[BUILD\](<\/string>)/$1$version$2/;
open(FH, ">$INFO") or die "$0: $INFO: $!";
print FH $info;
close(FH);
Как новый пользователь Stack Overflow, я не могу комментировать сообщение Куинна, но у меня есть небольшое изменение, чтобы сделать его решение более точным, если вы используете репозиторий SVN, который имеет несколько проектов, выполняемых одновременно.
Используя его подход, возвращаемый номер svnversion является последней проверкой для всего репозитория, не обязательно для вашей базы кода. Этот твик позволяет сделать обновление специфичным для вашей базы кода.
REV=`svnversion -nc | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $REV" "${TARGET_BUILD_DIR}"/${INFOPLIST_PATH}
Использование флага -c соберет последнюю фиксацию, сделанную в активной ветке / теге / стволе для вашей кодовой базы, в форме:, а затем отрежет биты вы не хотите сохранять как номер редакции.
Также обратите внимание на двойные кавычки вокруг $ {TARGET_BUILD_DIR}. Они нужны пользователям, которые решили разместить свой проект в структуре каталогов с пробелами в имени.
Я нашел эту страницу при попытке сделать подобную вещь для моего приложения для iPhone и подумал, что это может быть полезно поделиться кодом, на котором я решил. Я пытался установить номер базовой версии в моей целевой информации (например, 0.9.5), но затем добавьте мой номер ревизии SVN в конце этого. Мне нужно было сохранить в CFBundleVersion, чтобы пользователи ADHOC смогут обновить через iTunes, даже если я не помню, чтобы пересматривать номер версии в моей панели целевой информации. Вот почему я не мог использовать метод «Revision.h», который в противном случае прекрасно работал. Вот окончательный код, который я остановился, на котором я поместил в качестве фазы сценариев запуска сразу после фазы сборки «Ресурсы Copy Bundle»:
BASEVERNUM=`/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "${INFOPLIST_FILE}" | sed 's/,/, /g'`
REV=`svnversion -n`
SVNDATE=`LC_ALL=C svn info | awk '/^Last Changed Date:/ {print $4,$5}'`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BASEVERNUM.$REV" "${TARGET_BUILD_DIR}"/${INFOPLIST_PATH}
/usr/libexec/PlistBuddy -c "Set :BuildDateString $SVNDATE" "${TARGET_BUILD_DIR}"/${INFOPLIST_PATH}
Это должно добавить результаты Svnversion к концу все, что установлено в базовой информации. Plist как версия. Таким образом, вы можете иметь что-то вроде 0,9,5 в вашем информационном фильсте и до сих пор есть номер ревизии .189, добавленный в конце, давая конечную версию 0.9.5.189
Надеюсь, это поможет кому-то еще!
Другая версия, написанная в Apple Script. Regexp для предыдущихValue можно изменить, в настоящее время он поддерживает только версии в формате xx.xx.xx (основной, несовершеннолетний, SVN Rev).
Продолжительность / usr / bin / osascript
set myVersion to do shell script "svn info | grep \"^Revision:\""
set myVersion to do shell script "echo " & quoted form of myVersion & "| sed 's/Revision: \\([0-9]\\)/\\1/'" as string
set myFile to do shell script "echo ${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/"
set theOutputFolder to myFile as string
set thePListPath to POSIX path of (theOutputFolder & "Info.plist")
tell application "System Events"
tell property list file thePListPath
tell contents
set previousValue to value of property list item "CFBundleVersion"
set previousValue to do shell script "echo " & quoted form of previousValue & "| sed 's/\\([0-9]*\\.[0-9]*\\)\\(\\.[0-9]*\\)*/\\1/'" as string
set value of property list item "CFBundleVersion" to (previousValue & "." & myVersion)
end tell
end tell
end tell