我需要从我的视图控制器调用类方法,让它做它的事情,但然后只在类方法完成后执行一些操作.
(我认为我需要的是一个完成块,但如果我错了请纠正我.)
情况如下:
我正在使用Parse.com作为我的应用程序的后端.当用户注册帐户时,他们会在弹出窗口中输入他们的姓名,公司和其他信息,然后单击"提交".提交按钮链接到一个类方法(如下所示),该方法获取其PFUser对象和公司名称并创建一些数据库对象.函数完成后,使用委托解除弹出窗口.
问题是我需要按特定顺序创建这些对象,因为它们依赖于彼此对象的存在.问题是,在单击提交后立即调用解除弹出窗口的委托方法,因为它是堆栈中的下一个.
保存Parse对象时,会调用一个看起来像这样的方法:(这是我希望编写的,我认为可以解决我的问题)
[someParseObject saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) { // Code here runs AFTER the method completes. // This also happens on another thread which // I'd like to implement as well. }];
所以,我需要弄清楚如何做以下事情:(与块有关的一切都是完全错误的我确定)
SignUpViewController.m myUserOrg *userOrg = [myUserOrg object]; // myUserOrg = Custom PFObject Subclass // My method that takes in a user object and a string, creates // the database objects in order. [userOrg registerNewUserOrgWithUser:(PFUser*) andCompanyName:(NSString*) companyName withBlock(somethingHere)block { if(error) { NSLog(@"Unable to create org!"); } else { NSLog(@"Created Org!"); [self.delegate dismissSignupView]; }
如果您需要其他信息或说明,请与我们联系.
先感谢您!
---------编辑一个----------
好吧,以后几个相当大的时间单位,这就是我想出来的.整个实现可以更好地简化,并减少api调用,但会对此有所帮助.其他几个明显的问题也是第一步.
方法调用:
[testOrg registerNewUserOrgWithUser:currentUser creatingOrgContactWithName:@"MyBigHappy Corp." withBlock:^(BOOL succeeded, NSError *error) { if (error) { NSLog(@"Not working"); } else { NSLog(@"Working!"); } }];
方法实施:
@implementation MYUserOrg @dynamic orgContact; @dynamic orgDisplayName; @dynamic members; @dynamic contacts; + (NSString *)parseClassName { return @"MYUserOrg"; } dispatch_queue_t NewUserOrgRegistrationQueue; -(void)registerNewUserOrgWithUser:(MYUser*)user creatingOrgContactWithName:(NSString*) orgContactName withBlock:(MYBooleanResultBlock) block { NewUserOrgRegistrationQueue = dispatch_queue_create("com.myapp.initialOrgCreationQueue", NULL); dispatch_async(NewUserOrgRegistrationQueue, ^{ NSMutableArray *errors = [[NSMutableArray alloc] init]; // Initial org save to generate objectId NSError *orgSaveError = nil; [self save:&orgSaveError]; if (orgSaveError) { [errors addObject:@"Initial Org save Failed"]; } // Create and Relate Org Contact NSError *saveOrgContactError = nil; MYontact *orgContact = [MYContact object]; [orgContact setContactType:MYContactTypeUserOrganization]; [orgContact setDisplayName:orgContactName]; [orgContact setParentOrg:self]; [orgContact save:&saveOrgContactError]; if (saveOrgContactError) { [errors addObject:@"Saving Org Contact Failed"]; } else { // If Org contact saved, set it; [self setOrgContact:orgContact]; } // Create amd Relate User Contact NSError *saveUserContactError = nil; MYContact *userContact = [MYContact object]; [userContact setFirstName:user.firstName]; [userContact setLastName:user.lastName]; [userContact setContactType:MYcontactTypeUser]; [userContact setParentOrg:self]; [userContact save:&saveUserContactError]; if (saveUserContactError) { [errors addObject:@"Saving user contact failed"]; } NSError *saveUserError = nil; [user setParentOrg:self]; [user setUserContact:userContact]; [user save:&saveUserError]; if (saveUserError) { [errors addObject:@"Saving User failed"]; } // Return if block succeeded and any errors. NSError *error = nil; BOOL succeeded; if (errors.count > 0) { NSDictionary *userInfo = @{@"error" : errors}; errors = [NSError errorWithDomain:@"MyAppErrorDomain" code:1 userInfo:userInfo]; succeeded = NO; } else { succeeded = YES; } block(succeeded, error); }); } @end
CW0007007.. 82
当我想写一个块时,我总是使用它:
http://fuckingblocksyntax.com
编辑
如果您正在编写Swift,请使用以下命令:
http://fuckingswiftblocksyntax.com
如果由于淫秽语言而导致上述链接无法打开,请使用此链接.
http://goshdarnblocksyntax.com/
当我想写一个块时,我总是使用它:
http://fuckingblocksyntax.com
编辑
如果您正在编写Swift,请使用以下命令:
http://fuckingswiftblocksyntax.com
如果由于淫秽语言而导致上述链接无法打开,请使用此链接.
http://goshdarnblocksyntax.com/
我为一个类写了一个completionBlock,它将在它们被震动后返回一个骰子的值:
使用returnType定义typedef(.h
上面的@interface
声明)
typedef void (^CompleteDiceRolling)(NSInteger diceValue);
@property
为块定义a (.h
)
@property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;
用finishBlock
(.h
)定义方法
- (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
在.m
文件中插入先前定义的方法并提交finishBlock
到@property
之前定义的
- (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{ self.completeDiceRolling = finishBlock; }
触发completionBlock
传递预定义的variableType给它(不要忘记检查是否completionBlock
存在)
if( self.completeDiceRolling ){ self.completeDiceRolling(self.dieValue); }
您将块定义为自定义类型:
typedef void (^ButtonCompletionBlock)(int buttonIndex);
然后将它用作方法的参数:
+ (SomeButtonView*)buttonViewWithTitle:(NSString *)title cancelAction:(ButtonCompletionBlock)cancelBlock completionAction:(ButtonCompletionBlock)completionBlock
在代码中调用它时,它就像任何其他块一样:
[SomeButtonView buttonViewWithTitle:@"Title" cancelAction:^(int buttonIndex) { NSLog(@"User cancelled"); } completionAction:^(int buttonIndex) { NSLog(@"User tapped index %i", buttonIndex); }];
如果需要触发块,只需调用completionBlock()(其中completionBlock是块的本地副本的名称)
关于http://goshdarnblocksyntax.com/
作为局部变量:
returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};
作为财产:
@property (nonatomic, copy) returnType (^blockName)(parameterTypes);
作为方法参数:
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;
作为方法调用的参数:
[someObject someMethodThatTakesABlock:^returnType (parameters) {...}];
作为typedef:
typedef returnType (^TypeName)(parameterTypes); TypeName blockName = ^returnType(parameters) {...};