Если вы хотите передавать данные с одного контроллера на другой, попробуйте этот код
FirstViewController.h
@property (nonatomic, retain) NSString *str;
SecondViewController.h
@property (nonatomic, retain) NSString *str1;
FirstViewController.m
- (void)viewDidLoad
{
// message for the second SecondViewController
self.str = @"text message";
[super viewDidLoad];
}
-(IBAction)ButtonClicked
{
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
secondViewController.str1 = str;
[self.navigationController pushViewController:secondViewController animated:YES];
}
Как уже отмечалось, vapply
выполняет две функции:
Второй момент - большее преимущество, поскольку он помогает ловить ошибки до их возникновения и приводит к более надежному коду. Эта проверка возвращаемого значения может быть сделана отдельно с помощью sapply
, а затем stopifnot
, чтобы убедиться, что возвращаемые значения соответствуют ожидаемым, но vapply
немного проще (если они более ограничены, так как пользовательский код проверки ошибок может проверять значения в пределах границ и т. д.).
Вот пример vapply
, гарантирующий, что ваш результат будет таким, как ожидалось. Это сравнивает то, над чем я только что работал, в то время как PDF-скребок, где findD
использовал regex для соответствия шаблону в необработанных текстовых данных (например, у меня был бы список, который был split
сущностью , и регулярное выражение для соответствия адресам внутри каждого объекта. Иногда PDF-код был преобразован вне порядка, и для объекта было бы два адреса, что вызвало нехорошее состояние.)
> input1 <- list( letters[1:5], letters[3:12], letters[c(5,2,4,7,1)] )
> input2 <- list( letters[1:5], letters[3:12], letters[c(2,5,4,7,15,4)] )
> findD <- function(x) x[x=="d"]
> sapply(input1, findD )
[1] "d" "d" "d"
> sapply(input2, findD )
[[1]]
[1] "d"
[[2]]
[1] "d"
[[3]]
[1] "d" "d"
> vapply(input1, findD, "" )
[1] "d" "d" "d"
> vapply(input2, findD, "" )
Error in vapply(input2, findD, "") : values must be length 1,
but FUN(X[[3]]) result is length 2
Как я говорю мои ученики, часть становления программистом, меняют ваше мышление с «ошибок раздражают» на «ошибки - мой друг».
Входы нулевой длины Одна связанная точка состоит в том, что если входная длина равна нулю, sapply
всегда будет возвращать пустой список, независимо от типа ввода. Сравнение:
sapply(1:5, identity)
## [1] 1 2 3 4 5
sapply(integer(), identity)
## list()
vapply(1:5, identity)
## [1] 1 2 3 4 5
vapply(integer(), identity)
## integer(0)
С помощью vapply
вы гарантированно получите определенный тип вывода, поэтому вам не нужно писать дополнительные проверки на входы с нулевой длиной.
Тесты
vapply
могут быть немного быстрее, потому что он уже знает, в каком формате он должен ожидать результатов.
input1.long <- rep(input1,10000)
library(microbenchmark)
m <- microbenchmark(
sapply(input1.long, findD ),
vapply(input1.long, findD, "" )
)
library(ggplot2)
library(taRifx) # autoplot.microbenchmark is moving to the microbenchmark package in the next release so this should be unnecessary soon
autoplot(m)
[/g1]
Если вы всегда хотите, чтобы ваш результат был чем-то конкретным ... например. логический вектор. vapply
делает это, но sapply
не обязательно это делает.
a<-vapply(NULL, is.factor, FUN.VALUE=logical(1))
b<-sapply(NULL, is.factor)
is.logical(a)
is.logical(b)
Дополнительные нажатия клавиш, связанные с vapply
, могут сэкономить время на отладку запутанных результатов позже. Если функция, которую вы вызываете, может возвращать разные типы данных, обязательно следует использовать vapply
.
Одним из примеров, который приходит на ум, будет sqlQuery
в пакете RODBC
. Если есть ошибка при выполнении запроса, эта функция возвращает вектор character
с сообщением. Например, скажем, вы пытаетесь выполнить итерацию по вектору имен таблиц tnames
и выберите максимальное значение из числового столбца NumCol в каждой таблице с помощью:
sapply(tnames,
function(tname) sqlQuery(cnxn, paste("SELECT MAX(NumCol) FROM", tname))[[1]])
Если все имена таблиц действительны, это приведет к созданию вектора numeric
. Но если одно из имен таблиц происходит в базе данных и запрос не выполняется, результаты будут принудительно введены в режим character
. Однако использование vapply
с FUN.VALUE=numeric(1)
остановит здесь ошибку и не позволит ей появиться где-то по линии --- или, что еще хуже, совсем нет.