Вы можете передать блок асинхронной функции и затем вызвать его при вызове обработчика завершения сеанса URL. Это тривиальный пример:
- (void)doSomethingWithBlock:(void (^)(double, double))block {
...
block(21.0, 2.0);
}
Я поднял этот ^^ из Apple Docs , но вы можете сделать что-то вроде этого: (Примечание: я не проверял это в компиляторе!)
-(void)getAsyncAnswerFor:(NSString*) str completion:(void (^)(NSData, NSURLResponse, NSError))block {
NSString *surl = [NSString stringWithFormat: @"https://~.com//api.php?q=%@",str];
NSURL *url = [NSURL URLWithString:surl];
NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession]
dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
block(data, response, error);
}];
[downloadTask resume];
}
Вам нужно быть осторожным, если вы попытаетесь сослаться на self
в любом месте блоков.
Кажется, это невозможно при использовании XAML. Пользовательские элементы управления кажутся излишними, когда у меня есть все необходимые элементы управления, но мне просто нужно сгруппировать их вместе с небольшим количеством логики и разрешить именованный контент.
Решение в блоге JD как Маккенир предполагает, похоже, лучший компромисс. Способ расширения решения JD, позволяющий определять элементы управления в XAML, может быть следующим:
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
var grid = new Grid();
var content = new ContentPresenter
{
Content = Content
};
var userControl = new UserControlDefinedInXAML();
userControl.aStackPanel.Children.Add(content);
grid.Children.Add(userControl);
Content = grid;
}
В моем примере выше я создал пользовательский элемент управления с именем UserControlDefinedInXAML, который определяется как любые обычные пользовательские элементы управления, использующие XAML. В моем UserControlDefinedInXAML у меня есть StackPanel с именем aStackPanel, внутри которого я хочу, чтобы мое именованное содержимое появлялось.
Ответ - не использовать для этого UserControl.
Создайте класс, который расширяет ContentControl
public class MyFunkyControl : ContentControl
{
public static readonly DependencyProperty HeadingProperty =
DependencyProperty.Register("Heading", typeof(string),
typeof(HeadingContainer), new PropertyMetadata(HeadingChanged));
private static void HeadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((HeadingContainer) d).Heading = e.NewValue as string;
}
public string Heading { get; set; }
}
, затем используйте стиль, чтобы указать содержимое
<Style TargetType="control:MyFunkyControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="control:MyFunkyContainer">
<Grid>
<ContentControl Content="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
и, наконец, - используйте его
<control:MyFunkyControl Heading="Some heading!">
<Label Name="WithAName">Some cool content</Label>
</control:MyFunkyControl>