我有一个返回NSRange的方法。当我从类外部调用此方法时,我遇到编译错误。
NSRange tmpRange;
tmpRange = [phrase rangeInString:searchString forString:theLetter goingForward:YES];
return tmpRange.location == -1;
<。>文件中的:
#import <Foundation/Foundation.h>
@interface Phrase : NSObject {
}
- (NSRange) rangeInString:(NSString *) tgt forString:(NSString *) find goingForward:(BOOL) fwd;
@end
通过其他方法在Phrase对象中调用此方法没有问题。编译器说'赋值中的不兼容类型'。
任何人都可以向我解释这个吗?我假设它与返回在对象外部生成的NSRange / struct类型值有关,但我不知道它为什么在一个地方而不是另一个地方工作。
答案 0 :(得分:5)
当然一个方法可以返回NSRange。但是返回结构需要特别注意编译器,因为调用方法的方式通常不同(objc_msgSend_stret
与objc_msgSend
)。
请务必将phrase
声明为
Phrase* phrase = ...;
以便编译器知道-rangeInString:…
正在返回NSRange,而不是
id phrase = ...;
(另外,由于您没有显示编译器错误的哪一行,请确保使用return … == -1;
的函数返回BOOL而不是NSRange。)
答案 1 :(得分:2)
方法可以返回NSRange吗?
是
通过其他方法在Phrase对象中调用此方法没有问题。 ...当我从类外部调用此方法时,我收到编译错误。 ......编译器说“分配中的不兼容类型”。
请记住#import
Phrase.h到您正在与Phrase对象交谈的实现文件中。否则,编译器不知道您的rangeOfString:forString:goingForward:
方法,而假设它返回id
。它需要头文件中的@interface
知道该方法返回NSRange
。
假设您的短语对象位于实例变量中,您可能在声明了ivar的头文件中声明了带有@class Phrase;
的Phrase类。那是一个前瞻性声明;它告诉编译器存在一个名为“Phrase”的类(因此像Phrase *myPhrase
这样的声明是合法的),但它并没有告诉编译器有关它的任何其他内容。为此,您需要导入标题。
对于知道B类实例的A类实例,一般规则是A的标题(Ah)用@class
转发B类,A用于导入B标题的实现(Am)( BH)。
另一种情况是当A是B的子类时。你需要@interface
来创建一个子类,所以在这种情况下只有这种情况,A.h必须导入B.h.由于它导入了B的标题,因此不需要向前声明B。
答案 2 :(得分:1)
我不认为这是答案,但NSRange.location被声明为NSUInteger。通过将其与-1进行比较,您将无符号值与有符号值进行比较。
我能想到的另一个答案是你正在进行调用的.m文件没有导入标题Phrase.h。现在,我知道你相信它,但编译器却说不然。尝试在文件上运行预处理器以查看它实际导入的内容。 (右键单击包含.m文件的编辑器 - 预处理位于弹出的上下文菜单的底部附近。)
答案 3 :(得分:1)
是的,您可以在方法中返回C结构。那不是问题。此外,location是NSUInteger,永远不会是-1。使用NSNotFound来测试它。
如何输入您的词组对象的实例?您使用的是id
而不是Phrase *
吗?你有没有正确导入短语标题?
您应该向我们提供有关给出编译错误的代码的更多信息。
答案 4 :(得分:1)
回应即将出现的一些问题:
#import <Foundation/Foundation.h>
#import "OverlayView.h"
#import "Phrase.h"
#import "TimerPaneView.h"
是MainPane.h中的标题,是用于调用的类的标题。
在MainPane.h的标题中,声明了短语:
Phrase *phrase;
在实现文件中,是的,导入MainPane标头:
phrase = [[Phrase alloc] init];
在initWithFrame方法中是如何实例化短语类。我引用了几十个和几十个短语对象,调用方法,引用这个类中的属性,没有问题。不,短语对象永远不会释放,直到dealloc。
- 补充说:我以为我找到了问题:一个从未被调用的代码的折叠部分,其具有BOOL的遗留返回值。此方法最初返回BOOL,但已转换。但是我把它消灭了,问题仍然存在。
我还应该说我已经重新解决了这个问题,但它仍然是一个谜......