调用可选协议方法时崩溃

时间:2013-07-17 10:34:11

标签: iphone ios protocols

我使用一些带有一些可选方法的协议。

@protocol PhotoDropDownDelegate <NSObject>

@optional
    - (void)getEditResult:(NSString *)status;
    - (void)getImageForDiagram:(UIImage *)image andImagePath:(NSString *)imagePath;
    - (void)dismissPhotoDropDown;

@end

我为一个班级

指定了这个
photoDropDownViewController.photoDropDownDelegate = self;

我只使用一种方法

- (void)getImageForDiagram:(UIImage *)image andImagePath:(NSString *)imagePath
{
    // Make a Image on center of screen
    PhotoLayer *photoLayer = [PhotoLayer nodeWithLengthOfShape:300 andHeight:200 andPathToImage:imagePath];
    photoLayer.position = ccp(400, 500);
    photoLayer.nameObject = [self makeNewName_ForShape];    
    photoLayer.isSelected_BottomRightElip = YES;
    photoLayer.isSelected = YES;


    [photoLayer doWhenSelected_Elip_BottomRight];
    [photoLayer show_Elip];

    [list_Shapes addObject:photoLayer];

    [self addChild:photoLayer];
    photoLayer = nil;

    // Set Button Delete
    selected_GerneralShapeLayer = (GerneralShapeLayer *) [list_Shapes lastObject];
    [self updateStatusForButtonDelete];
}

然后编译器显示错误:

  

[AddDiagramLayer dismissPhotoDropDown]: unrecognized selector sent to instance 0xb2a8320'

当我实现其他方法时,错误消失

-(void)getEditResult:(NSString *)status {

}

-(void)dismissPhotoDropDown {

}

正如我所知,如果@option中的方法我们可以使用或不使用它。 我不明白这里发生了什么。任何人都可以向我解释

1 个答案:

答案 0 :(得分:11)

如果未实现可选方法,则所有@optional指令都会抑制编译器警告。但是,如果您调用该类未实现的方法,则应用程序仍将崩溃,因为您尝试调用的选择器(方法)未被类识别,因为它未实现。

您可以通过检查委托是否在调用之前实现方法来解决此问题:

// Check that the object that is set as the delegate implements the method you are about to call
if ([self.photoDropDownDelegate respondsToSelector:@selector(dismissPhotoDropDown)]) {
    // The object does implement the method, so you can safely call it.
    [self.photoDropDownDelegate dismissPhotoDropDown];
}

这样,如果委托对象实现了一个可选方法,那么它将被调用。否则,它不会,您的程序将继续正常运行。

请注意,您仍应使用@optional指令来表示可实现的可选方法,以避免在未实现编译器警告时发出警告。这对于将分发给客户端的开源软件或库尤其重要,因为该指令告诉开发人员没有读取您的实现,但只能看到标题,他们不需要实现这些方法,以及一切都会好起来的。