The ARC migration tool is refusing to accept this code prior to starting with migration:
[self.delegate performSelector:@selector(overlayDismissed:) withObject:self afterDelay:0];
The delegate is forced to implement this method with a protocol, and it should work fine:
@protocol OverlayDelegate <NSObject>
- (void)overlayDismissed:(Overlay*)overlay;
@end
@interface Overlay : UIImageView {
id<OverlayDelegate> delegate;
}
@property (nonatomic, assign) id<OverlayDelegate> delegate;
What's wrong with ARC? Why is it telling me that there is "no known instance method for selector 'performSelector:withObject:afterDelay:'?
Simple, your object is of type
id
and conforms to theNSObject
protocol. However, this protocol doesn't declareperformSelector:withObject:afterDelay:
, so ARC doesn't know what the method is doing and if it must retain anything. Either use an NSObject or cast it prior to making the method call.ARC isn't causing this - it is is merely exposing it. That method is defined on NSObject - but id works for more than just NSObject (so you have to be more specific than just 'id'). Change your code to this:
I've figured out that casting the delegate to NSObject* solves the problem:
For some weird reason autocompletion did not even come up with
-performSelector:withObject:afterDelay:
so I had to type it manually. Instead, it offered only-performSelector:
and-performSelector:withObject:withObject:
My guess is that it's just stupid to use id as the type for delegates in Objective-C, and I never really knew why everyone including myself is doing that rather than just defining it as NSObject. However, my protocol even told that whoever conforms to that protocol also has to conform to the NSObject protocol by doing this:
OverlayDelegate <NSObject>
- and still, the compiler didn't get it.So for now I'm satisfied it works with the cast, but it feels like eating old fish.
I met error:
The reason is that : file name is not equal to the class name with
@interface
and@implementation
.