调用可选协议方法时崩溃

use*_*837 0 iphone protocols ios

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

@protocol PhotoDropDownDelegate <NSObject>

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

@end
Run Code Online (Sandbox Code Playgroud)

我把它分配给一个班级

photoDropDownViewController.photoDropDownDelegate = self;
Run Code Online (Sandbox Code Playgroud)

我只使用一种方法

- (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];
}
Run Code Online (Sandbox Code Playgroud)

然后编译器显示错误:

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

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

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

}

-(void)dismissPhotoDropDown {

}
Run Code Online (Sandbox Code Playgroud)

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

Gre*_*reg 12

@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];
}
Run Code Online (Sandbox Code Playgroud)

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

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