首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何编写目标-C完成块

如何编写目标-C完成块
EN

Stack Overflow用户
提问于 2014-01-29 16:26:44
回答 5查看 79.6K关注 0票数 46

在这种情况下,我需要从我的视图控制器调用一个类方法,让它执行它的事情,但是只在类方法完成之后才执行一些操作。

(我想我需要的是一个完整的街区,但如果我错了,请纠正我。)

情况如下:

我使用Parse.com作为我的应用程序后端。当用户注册一个帐户时,他们会在弹出窗口中输入他们的名字、公司和其他信息,然后点击submit。submit按钮链接到一个类方法(如下图所示),该方法接受它们的PFUser对象和公司名称,并创建一些数据库对象。函数完成后,弹出窗口将使用委托被取消。

问题是,我需要以特定的顺序创建这些对象,因为它们相互依赖,对象的存在。问题是,在单击submit之后立即调用委托方法来取消弹出窗口,因为它是堆栈上的下一个。

当保存一个Parse对象时,调用一个类似于这样的方法:(这是我希望编写的,我认为它可以解决我的问题)

代码语言:javascript
复制
[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.
}];

所以,我需要知道如何做以下事情:(与这个块有关的一切都是完全错误的,我敢肯定)

代码语言:javascript
复制
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调用,但会在这方面发挥作用。其他几个突出的问题也与它有关,但这是第一步。

方法调用:

代码语言:javascript
复制
[testOrg registerNewUserOrgWithUser:currentUser
         creatingOrgContactWithName:@"MyBigHappy Corp."
                          withBlock:^(BOOL succeeded, NSError *error) {
                              if (error) {
                                  NSLog(@"Not working");
                              } else {
                                  NSLog(@"Working!");
                              }
                          }];

方法实现:

代码语言:javascript
复制
@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
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-01-29 16:29:20

当我想要写一个块时,我总是使用它:

http://fuckingblocksyntax.com

编辑

如果您正在编写Swift,请使用以下内容:

http://fuckingswiftblocksyntax.com

如果上述链接由于淫秽语言而没有打开,请使用此链接。

http://goshdarnblocksyntax.com/

票数 100
EN

Stack Overflow用户

发布于 2014-12-10 13:46:39

我为一个类编写了一个completionBlock,该类将在一个骰子被抖动后返回它们的值:

  1. 用returnType (.h@interface声明上)定义类型胡枝子 胡枝子(NSInteger diceValue);
  2. 为块定义一个@property (.h) @property (复制,非原子) CompleteDiceRolling completeDiceRolling;
  3. finishBlock (.h)定义方法

  • (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;

  1. .m文件中插入先前定义的方法,并将finishBlock提交给前面定义的@property

  • (GetDiceValueAfterSpin):(void (^)(NSInteger diceValue))finishBlock{ self.completeDiceRolling = finishBlock;}

  1. 要触发completionBlock,请将预定义的variableType传递给它(不要忘记检查completionBlock是否存在) if( self.completeDiceRolling ){ self.completeDiceRolling(self.dieValue);}
票数 36
EN

Stack Overflow用户

发布于 2016-10-07 18:09:15

将块定义为自定义类型:

代码语言:javascript
复制
typedef void (^ButtonCompletionBlock)(int buttonIndex);

然后将其用作方法的参数:

代码语言:javascript
复制
+ (SomeButtonView*)buttonViewWithTitle:(NSString *)title 
                      cancelAction:(ButtonCompletionBlock)cancelBlock
                  completionAction:(ButtonCompletionBlock)completionBlock

在代码中调用它时,它就像任何其他块一样:

代码语言:javascript
复制
[SomeButtonView buttonViewWithTitle:@"Title"
                   cancelAction:^(int buttonIndex) {
                         NSLog(@"User cancelled");
               } 
                 completionAction:^(int buttonIndex) {
                         NSLog(@"User tapped index %i", buttonIndex);
               }];

如果触发块的时间到了,只需调用completionBlock() (其中completionBlock是块本地副本的名称)

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21436831

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档