我来自java世界,所以我的问题可能显得愚蠢。
当我有两个不同的实现类,同一个变量(NSString对象)名称时,为什么编译器会抱怨? 它们默认不是私有的吗? 这是被禁止的吗?是否有任何构建设置需要更改?
毕竟,因为我不在这里使用iVar,我是否用C / C ++风格声明了这个变量?
示例: SampleClass.h
#import <Foundation/Foundation.h>
@interface SampleClass : NSObject
{
...
}
@end
AnotherClass.h
#import <Foundation/Foundation.h>
@interface AnotherClass : NSObject
{
...
}
@end
SampleClass.m
#import "SampleClass.h"
@implementation SampleClass
NSString *myVar;
@end
AnotherClass.m
#import "AnotherClass.h"
@implementation AnotherClass
NSString *myVar;
@end
关于myVar变量的编译器响应: ld:1架构arm64的重复符号
编辑: -1;(( 世界可以如此宽容......
EDIT2 感谢upvote!还有希望;)
答案 0 :(得分:4)
您正在定义全局变量(这些变量是您的类中的不是变量!)。要使它们对您的文件“隐私”,请使用static
关键字:
static NSString *myVar;
如果你想要实例变量,你需要像这样定义它们:
@implementation SampleClass {
NSString *myVar;
}
@end
(请注意{
之后的}
和@implementation
。)
答案 1 :(得分:3)
您的声明并未将变量声明为成员变量 - 它声明了一个碰巧已在@implementation块中定义的全局变量。
如果你想把它定义为成员变量(或Objective-C术语中的“实例变量”),这里有一些信息。
ObjC的一般语法是:
@interface MyClass : NSObject {
// member-variable declarations visible to everybody
}
// member-function declarations visible to everybody
@end
您的实施应如下所示:
@implementation MyClass {
// member-variable declarations visible to only you
}
// member-function definitions
@end
要使其成为私有全局变量,您可以执行以下任何选项:
static NSString * variable = nil ; // note that this has to be a compile-time constant in Objective-C
如果您不知道,'static'关键字表示“内部链接” - 这意味着它不会将链接器作为其他文件可能要访问的变量公开,因此链接器甚至不会尝试(并且不会发现它们的重复。)
或者您可以将.m文件重命名为.mm(“Objective-C ++”)。您将被迫在编码方面更加严谨(因为现在您已经遵守C ++标准而不是C语言),但您可以做到这样的事情:
@implementation MyClass
namespace {
NSString * myString = @"someString" ;
NSString * myOtherString = someFunctionThatReturnsAString() ;
}
@end
虽然我不推荐使用后一种选择,直到你对C ++更加熟悉。