PFObject的saveInBackgroundWithBlock:方法 - 不调用块

时间:2014-10-05 06:55:36

标签: ios objective-c parse-platform pfobject

考虑这个简单的方法:

- (void)connectSpouseToCurrentUser:(PFUser *)spouse completionBlock:(void (^)(NSError *error))completionBlock {
    [PFUser currentUser][@"spouse"] = spouse;        
    [[PFUser currentUser] saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if (error) {
            NSLog(@"Error: %@", [error userInfo]);
        }

        spouse[@"spouse"] = [PFUser currentUser];
        [spouse saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
           // This code never executes
            NSLog(@"Error: %@", error);
            self.spouse = spouse;
            if (completionBlock) {
                completionBlock(error);
            }
        }];
    }];
}

由于某些原因,我的最新完成块未被调用。

有人知道为什么会这样吗?

3 个答案:

答案 0 :(得分:1)

对于使用Array列类型遇到此一对多关系问题的人,

如果将数组分配给Array列类型,则不会调用完成块。但是,数据已保存。但是,无法在parse.com仪表板中可视化连接。

我有两个表,用户和教育。用户可以拥有多个Education对象。在以下代码中,永远不会调用完成块。

import Parse

var education : [MyEducation] = [MyEducation]()

let edu1 : MyEducation = MyEducation()
edu1["schoolName"] = "Stanford"
edu1["fieldOfStudy"] = "Engineering"
edu1["startDate"] = NSDate()
education.append(edu1)

let edu2 : MyEducation = MyEducation()
edu2["schoolName"] = "UCLA"
edu2["fieldOfStudy"] = "Data Science"
edu2["startDate"] = NSDate()
education.append(edu2)

PFUser.currentUser()?["education"] = education
PFUser.currentUser()?.saveInBackgroundWithBlock{(success: Bool, error: NSError?) -> Void in
        let a : Int = 1
}

但是,如果您编写以下代码,则会调用完成块。

import Parse

var education : [MyEducation] = [MyEducation]()

let edu1 : MyEducation = MyEducation()
edu1["schoolName"] = "Stanford"
edu1["fieldOfStudy"] = "Engineering"
edu1["startDate"] = NSDate()
edu1["user"] = PFUser.currentUser()
education.append(edu1)

let edu2 : MyEducation = MyEducation()
edu2["schoolName"] = "UCLA"
edu2["fieldOfStudy"] = "Data Science"
edu2["startDate"] = NSDate()
edu2.["user"] = PFUser.currentUser()
education.append(edu2)

PFUser.currentUser()?.saveInBackgroundWithBlock{(success: Bool, error: NSError?) -> Void in
        let a : Int = 1
}

所以最后,选择哪种方法就是你的电话。前者使仪表板中的可视化更难(或不可能?),但您可以稍后使用includeKey(" education")进行PFUser查询。

在后一种方法中,您必须在Education类中查询完整的PFObject,但在仪表板中可以看到来自Education类的User指针以及调用完成块。

我认为Parse没有很好地设计关系获取,并且没有记录这种行为。

答案 1 :(得分:0)

您应该将代码设置在成功或!错误块中,如下所示:

if (succeeded) { // like this
    spouse[@"spouse"] = [PFUser currentUser];
    [spouse saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if (!error) { // or like this
           // This code never executes
            NSLog(@"Error: %@", error);
            self.spouse = spouse;
            if (completionBlock) {
                completionBlock(error);
            }
        }
    }];
}

答案 2 :(得分:0)

我有同样的问题,我在解析助手论坛上只发现了一个关于这个主题的有用评论。我试了一下它的确有效。 https://www.parse.com/questions/saveinbackgroundwithblock-not-being-called-on-1219

所以主要的问题是你创建了一个从用户到配偶以及从配偶到用户的指针。我知道使用这两个指针更容易。

在我的情况下,我有用户和消息,所有消息都有指向用户的指针,所有用户都有指向最后消息的指针。我删除了最后一个。当我需要一个新的消息并将其存储为正常的目标c proprerty时,我会从查询中查询最后一条消息而不是指针。

PFQuery *messageQuery = [Message query];
[messageQuery whereKey:@"owner" equalTo:self.createdBy];
[messageQuery orderByDescending:@"createdAt"];
[messageQuery getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
    if (object && !error)
    self.user.lastMessage = (Message *)object;
}];

希望这会对你有所帮助。另外,我强烈建议您使用parse子类化。编码和更好地了解你正在做的事情要容易得多。