Jak mogę przekazać Block
do Function
/Method
?Obiekt blokujący Objective-C jako parametr
Próbowałem - (void)someFunc:(__Block)someBlock
bezskutecznie.
tj. Co to jest typ dla Block
?
Jak mogę przekazać Block
do Function
/Method
?Obiekt blokujący Objective-C jako parametr
Próbowałem - (void)someFunc:(__Block)someBlock
bezskutecznie.
tj. Co to jest typ dla Block
?
Typ bloku różni się w zależności od jego argumentów i typu zwracanego. W ogólnym przypadku typy bloków są deklarowane w ten sam sposób, co funkcje typów wskaźników, ale zastępowanie *
za pomocą . Jednym ze sposobów przekazania bloku do metody jest:
- (void)iterateWidgets:(void (^)(id, int))iteratorBlock;
Ale jak widać, jest brudny. Zamiast tego można użyć typedef
aby typy bloków czystsze:
typedef void (^ IteratorBlock)(id, int);
a następnie przekazać ten blok do metody tak:
- (void)iterateWidgets:(IteratorBlock)iteratorBlock;
Dlaczego przekazujesz id jako argument? Czy nie można na przykład łatwo przekazać numeru NSNumber? Jak to wyglądałoby? – bas
Z pewnością można przekazać mocno napisany argument, taki jak 'NSNumber *' lub 'std :: string & 'lub cokolwiek innego, co można przekazać jako argument funkcji. To tylko przykład. (Dla bloku, który jest równoważny z wyjątkiem zastąpienia 'id' przez' NSNumber', 'typedef' będzie' typedef void (^ IteratorWithNumberBlock) (NSNumber *, int); '.) –
To pokazuje deklarację metody. Jednym z problemów z blokami jest to, że "bałaganiarski" styl deklaracji nie czyni jasnym i łatwym zapisanie faktycznego wywołania metody z rzeczywistym argumentem bloku. – uchuugaka
także można wywołać lub wywołać blok przy użyciu zwykłej składni funkcji c
Więcej informacji na blokach tutaj
Pomógł mi link do bls docs. –
Można również ustawić blok jako prosta własności, czy to dotyczy Ciebie:
@property (nonatomic, copy) void (^didFinishEditingHandler)(float rating, NSString *reviewString);
upewnić się, że nieruchomość jest blok „kopia”!
i oczywiście można również używać typedef:
typedef void (^SimpleBlock)(id);
@property (nonatomic, copy) SimpleBlock someActionHandler;
Można zrobić tak, przechodząc blok jako parametr bloku:
//creating a block named "completion" that will take no arguments and will return void
void(^completion)() = ^() {
NSLog(@"bbb");
};
//creating a block namd "block" that will take a block as argument and will return void
void(^block)(void(^completion)()) = ^(void(^completion)()) {
NSLog(@"aaa");
completion();
};
//invoking block "block" with block "completion" as argument
block(completion);
jeden sposób, aby przekazać blok przy użyciu funkcji с w przykład poniżej. Stworzyłem funkcje do wykonywania wszystkiego w tle i w głównej kolejce.
plik blocks.h
void performInBackground(void(^block)(void));
void performOnMainQueue(void(^block)(void));
plik blocks.m
#import "blocks.h"
void performInBackground(void(^block)(void)) {
if (nil == block) {
return;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), block);
}
void performOnMainQueue(void(^block)(void)) {
if (nil == block) {
return;
}
dispatch_async(dispatch_get_main_queue(), block);
}
niż import blocks.h gdy jest to konieczne i powołać go:
- (void)loadInBackground {
performInBackground(^{
NSLog(@"Loading something in background");
//loading code
performOnMainQueue(^{
//completion hadler code on main queue
});
});
}
Mimo odpowiedzi udzielonych na ten temat wątku, naprawdę starałem się napisać funkcję, która wzięłaby Blok jako funkcję - i z parametrem. W końcu mam rozwiązanie, które wymyśliłem.
Chciałem napisać ogólną funkcję, loadJSONthread
, która zajmie URL usługi sieciowej JSON, załaduję niektóre dane JSON z tego adresu URL w wątku tła, a następnie zwrócę NSArray * wyników z powrotem do funkcji wywołującej.
Zasadniczo chciałem ukryć całą złożoność wątku tła w ogólnej funkcji wielokrotnego użytku.
Oto jak Nazwałbym tę funkcję:
NSString* WebServiceURL = @"http://www.inorthwind.com/Service1.svc/getAllCustomers";
[JSONHelper loadJSONthread:WebServiceURL onLoadedData:^(NSArray *results) {
// Finished loading the JSON data
NSLog(@"Loaded %lu rows.", (unsigned long)results.count);
// Iterate through our array of Company records, and create/update the records in our SQLite database
for (NSDictionary *oneCompany in results)
{
// Do something with this Company record (eg store it in our SQLite database)
}
} ];
... i to jest nieco zmagałem się: jak to deklarują, i jak się go wywołać funkcję Zablokuj raz dane było załadowany, i przekazać Block
NSArray * zapisów załadowany:
+(void)loadJSONthread:(NSString*)urlString onLoadedData:(void (^)(NSArray*))onLoadedData
{
__block NSArray* results = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
// Call an external function to load the JSON data
NSDictionary * dictionary = [JSONHelper loadJSONDataFromURL:urlString];
results = [dictionary objectForKey:@"Results"];
dispatch_async(dispatch_get_main_queue(), ^{
// This code gets run on the main thread when the JSON has loaded
onLoadedData(results);
});
});
}
Ten StackOverflow pytanie dotyczy sposobu wywoływania funkcji, przekazując jako parametr bloku, więc ja uprościć powyższy kod i nie obejmowały loadJSONDataFromURL
funkcjonować.
Ale, jeśli jesteś zainteresowany, można znaleźć kopię tego JSON funkcji załadunku na tym blogu: http://mikesknowledgebase.azurewebsites.net/pages/Services/WebServices-Page6.htm
Nadzieja pomaga to kilka innych deweloperów XCode! (Nie zapomnij zagłosować maksymalnie na to pytanie i moja odpowiedź, jeśli to robi!)
To poważnie jedna z najlepszych sztuczek, jakie widziałem w ios i blokach. Uwielbiam to człowiek !!!! – portforwardpodcast
Napisałem completionBlock dla klasy, która będzie zwracać wartości kości po ich wstrząśnięty:
zdefiniować typedef z returnType (.h
powyżej @interface
zgłoszenie)
typedef void (^CompleteDiceRolling)(NSInteger diceValue);
Definiowanie @property
dla bloku (.h
)
@property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;
Zdefiniować metodę z finishBlock
(.h
)
- (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
Insert poprzedni określoną metodą w .m
pliku i zobowiązać finishBlock
do @property
zdefiniowane przed
- (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{
self.completeDiceRolling = finishBlock;
}
Aby wywołać completionBlock
wprost predefiniowane variableType do tego (Nie zapomnij sprawdzić, czy completionBlock
istnieje)
if(self.completeDiceRolling){
self.completeDiceRolling(self.dieValue);
}
zawsze zapominają o składni bloków. To zawsze przychodzi mi do głowy, kiedy muszę zadeklarować blok.Mam nadzieję, że ktoś pomaga :)
Najprostszym wyjaśnieniem tej kwestii jest następujące szablony:
1. Blok jako parametr metody
Szablon
- (void)aMethodWithBlock:(returnType (^)(parameters))blockName {
// your code
}
Przykład
-(void) saveWithCompletionBlock: (void (^)(NSArray *elements, NSError *error))completionBlock{
// your code
}
Inne zastosowania przypadkach:
2. Blok jako właściwość
Szablon
@property (nonatomic, copy) returnType (^blockName)(parameters);
Przykład
@property (nonatomic,copy)void (^completionBlock)(NSArray *array, NSError *error);
3. Blok jako sposób argumentu
Szablon
[anObject aMethodWithBlock: ^returnType (parameters) {
// your code
}];
Przykład
[self saveWithCompletionBlock:^(NSArray *array, NSError *error) {
// your code
}];
4. Blok w zmiennej lokalnej
Szablon
returnType (^blockName)(parameters) = ^returnType(parameters) {
// your code
};
Przykład
void (^completionBlock) (NSArray *array, NSError *error) = ^void(NSArray *array, NSError *error){
// your code
};
5.Blok jako typedef
Szablon
typedef returnType (^typeName)(parameters);
typeName blockName = ^(parameters) {
// your code
}
Przykład
typedef void(^completionBlock)(NSArray *array, NSError *error);
completionBlock didComplete = ^(NSArray *array, NSError *error){
// your code
};
Świetna odpowiedź dzięki bardzo. –
Świetna odpowiedź man.Far lepiej niż akceptowane one.Thanks. – abhi1992
Tak praktyczne i jasne, co sprawia, że ta odpowiedź jest najlepsza, moim zdaniem. – developermike
odniesienie, że mogę używać więcej niż Zależy mi się przyznać: http: // goshdarnblocksyntax. com/ – oltman
http://fuckingblocksyntax.com/ :) – aryaxt