Nó phụ thuộc vào những gì bạn đang cố gắng trở về. Nhưng điều có thể khiến bạn khó hiểu là nếu bạn phát hành câu lệnh return
từ bên trong khối inDatabase
, bạn sẽ trở về từ khối, bạn sẽ không trở về từ phương thức chứa khối inDatabase
này.
Vì vậy, bạn chỉ đơn giản là không trả lại giá trị từ khối inDatabase
, mà đúng hơn là bạn trả về các giá trị từ bên ngoài khối. Vì vậy, những gì bạn thường làm, bạn sẽ khai báo biến của mình để được trả về bên ngoài khối inDatabase
, khối inDatabase
của bạn sẽ cập nhật và sau đó, khi khối được thực hiện, đó là khi bạn trả lại kết quả (không phải từ trong khối inDatabase
).
Một ví dụ phổ biến là nếu bạn đang xây dựng một NSMutableArray
: Vì vậy, tạo ra các mảng có thể thay đổi bên ngoài của khối, và sau đó thêm giá trị từ bên trong khối, nhưng sau đó trả lại kết quả sau bạn thoát khỏi khối inDatabase
:
NSMutableArray *results = [NSMutableArray array]; // declare this outside the block
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(1)];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(2)];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(3)];
FMResultSet *rs = [db executeQuery:@"select * from foo"];
while ([rs next]) {
...
[results addObject:result]; // add values inside the block
}
[rs close];
}];
return results; // return the results outside the block
hoặc, nếu bạn đang làm việc với một số loại hình cơ bản, giống như một NSInteger
hoặc BOOL
hoặc những gì có bạn, bạn muốn khai báo biến với khuôn khổ vòng loại __block
. Ví dụ: tôi sẽ sử dụng điều này để trả về biến thành công của BOOL, ví dụ:
__block BOOL success; // again, define outside the block
NSMutableArray *results = [NSMutableArray array];
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(1)];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(2)];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @(3)];
FMResultSet *rs = [db executeQuery:@"select * from foo"];
if (!rs)
{
NSLog(@"%s: %@", __FUNCTION__, [db lastErrorMessage]);
success = NO; // set the value inside the block
return; // note, this doesn't exit the method; this exits this `inDatabase` block
}
while ([rs next]) {
...
}
[rs close];
success = YES; // another example of setting that `success` variable
}];
// so whether I successfully completed the block, or whether I hit the `return`
// statement inside the block, I'll fall back here, at which point I'll return my
// boolean `success` variable
return success; // don't return the value until after you exit the block
Mặc dù điều này có vẻ khó hiểu khi lần đầu tiên bạn gặp phải, điều này rất hữu ích khi hiểu điều này. Khi bạn bắt đầu sử dụng khối GCD rất nhiều, mẫu này rất phổ biến. Khi bạn có một khối (được chỉ định bởi ký tự ^
), bạn gần như phải nghĩ về nó như một hàm mà bạn đang xác định bên trong phương pháp chính của bạn. Khi bạn gặp một số return
bên trong một khối, bạn sẽ quay lại phương thức chứa khối đó.
Đối với giới thiệu đến khối xem:
những gì bạn muốn quay trở lại? Một giá trị duy nhất, hoặc một tập hợp (hoặc mảng) các kết quả từ db (đó là những gì nó trông giống như bạn đang cố gắng thực hiện thông qua "' select * '" trên đó) ??? –