0

I use a protocol with some optional methods.

@protocol PhotoDropDownDelegate <NSObject>

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

@end

I assign this for a class

photoDropDownViewController.photoDropDownDelegate = self;

I use only one method

- (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];
}

Then the compiler show error:

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

when I implement the others methods the error is disappear

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

}

-(void)dismissPhotoDropDown {

}

As I've known, if a method in @option we can use it or not. I don't understand what happened here. Can anyone explain to me

4

1 回答 1

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];
}

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

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

于 2013-07-17T10:41:49.890 回答