Can a method return an NSRange?
I have a method that returns an NSRange. When I call this method from outside the class I get a compile error.
NSRange tmpRange;
tmpRange = [phrase rangeInString:searchString forString:theLetter goingForward:YES];
return tmpRange.location == -1;
in the .h file:
#import <Foundation/Foundation.h>
@int开发者_运维问答erface Phrase : NSObject {
}
- (NSRange) rangeInString:(NSString *) tgt forString:(NSString *) find goingForward:(BOOL) fwd;
@end
This method is called within the Phrase object by other methods without problems. The compiler says 'incompatible types in assignment'.
Can anyone explain this to me? I assume it has to do with returning an NSRange/struct type value generated outside the object, but I don't know why it works in one place and not the other.
Of course a method can return NSRange. But returning structures require special attention to the compiler because how the method is invoked is usually different (objc_msgSend_stret
vs. objc_msgSend
).
Please make sure you declare phrase
as
Phrase* phrase = ...;
so that the compiler knows -rangeInString:…
is returning an NSRange, instead of
id phrase = ...;
(Also, since you don't show which line the compiler errors, make sure the function using return … == -1;
is returning a BOOL not NSRange.)
Can a method return an NSRange?
Yes.
This method is called within the Phrase object by other methods without problems. … When I call this method from outside the class I get a compile error. … The compiler says 'incompatible types in assignment'.
Remember to #import
Phrase.h into the implementation file where you're talking to a Phrase object. Otherwise, the compiler doesn't know about your rangeOfString:forString:goingForward:
method and assumes that it returns id
. It needs the @interface
in the header file to know that the method returns NSRange
.
Assuming that your phrase object is in an instance variable, you probably declared the Phrase class with @class Phrase;
in the header file where you declared the ivar. That's a forward declaration; it tells the compiler that a class named “Phrase” exists (so that a declaration like Phrase *myPhrase
will be legal), but it doesn't tell the compiler anything else about it. To do that, you need to import the header.
The general rule, for instances of class A knowing about instances of class B, is for A's header (A.h) to forward-declare class B with @class
, and A's implementation (A.m) to import B's header (B.h).
A different case is when A is a subclass of B. You need the @interface
to make a subclass, so in this case and this case only, A.h must import B.h. Since it's importing the header for B, it does not need to forward-declare B.
I don't think this is the answer, but NSRange.location is declared as NSUInteger. By comparing it to -1, you are comparing an unsigned value to a signed value.
The only other answer I can think of is that the .m file you are making the call from has not imported the header Phrase.h. Now, I know you believe it has, but the compiler is saying otherwise. Try running the preprocessor on the file to see what it is actually importing. (right click in an editor containing the .m file - preprocess is near the bottom of the context menu that pops up).
Yes, you can return C structs in methods. That is not the problem. Also, location is an NSUInteger and will never be -1. Use NSNotFound to test for that.
How is the instance of your Phrase object typed? Did you use id
instead of Phrase *
? Have you properly imported the Phrase header?
You should give us more information about the code that's giving the compile error.
In response to some questions that are coming up:
#import <Foundation/Foundation.h>
#import "OverlayView.h"
#import "Phrase.h"
#import "TimerPaneView.h"
Is the header in the MainPane.h, the class header for where the call is being made.
In the header for MainPane.h, phrase is declared:
Phrase *phrase;
And in the implementation file, which, yes, imports the MainPane header:
phrase = [[Phrase alloc] init];
Is how the phrase class is being instantiated, in the initWithFrame method. I refer to the phrase object dozens and dozens of times, calling methods, referring to properties in this class, without problems. And no, the phrase object is never released until dealloc.
-- added: I thought I had found the problem: a collapsed section of code that never is called that had a legacy return value that was BOOL. This method originally returned BOOL, but was converted. But I eliminated it, and the problem remains.
I should also say that I've refactored my way around this problem, but it remains a mystery...
精彩评论