Objective-C访问公共方法

9
我尝试从另一个类中访问公共方法。我已经尝试了许多在网上找到的示例,但它们并没有按照我想要的方式工作。

Class1.h

@interface anything : NSObject {

    IBOutlet NSTextField *label;

}

+ (void) setLabel:(NSString *)string;
- (void) changeLabel:(NSString *)string2;

Class1.m

+ (void) setLabel:(NSString *)string {

    Class1 *myClass1 = [[Class1 alloc] init];

    [myClass1 changeLabel:string];
    NSLog(@"setLabel called with string: %@", string);

}

- (void) changeLabel:(NSString *)string2 {

    [label setStringValue:string2];
    NSLog(@"changeLabel called with string: %@", string2);
}

Class2.m

- (IBAction)buttonPressed {

    [Class1 setLabel:@"Test"];

}

非常奇怪的是,在NSLogs中一切正常,两个NSLogs中的字符串都是“Test”,但textField的stringValue没有改变!

1
你混淆了类方法和对象方法。这个例子并没有真正意义上的作用。 在 + setLabel: 中,你只是暂时创建了一个对象,但你从未对它进行任何操作/也没有返回它。告诉我你想做什么,这样我才能帮助你。 - IluTov
1
为什么要使用静态方法?这是单例模式吗? - Ramy Al Zuhouri
@RamyAlZuhouri 不,这不是单例模式,那需要一个静态变量。 - IluTov
我现在看得很清楚,他正在分配一个新的类实例:胡说八道。 - Ramy Al Zuhouri
4个回答

15

-+ 不表示公有或私有。

- 代表可以在类的对象上调用的方法,而

+ 代表可以在类本身上调用的方法。


啊,好的。那跟Java有什么不同吗?还是我理解错了什么? - Vincent Friedrich
在 Objective-C 中基本上没有私有函数... 在头文件中定义的每个函数都是公共的... 如果你仍然想定义私有函数以便它们在某处被提到,可以像 https://dev59.com/aHVC5IYBdhLWcg3w1Exq#651852 中所述,在 .m 文件中添加一个块。 - Infinite
3
好的回答,尽管严格来说这些是“方法”,而不是“函数”。 - jlehr
12
换句话说,+ 表示静态的,而 - 表示非静态的。 - string.Empty

8

以下是一个简单的示例,您可以参考此示例进行操作:


自定义类

@interface ITYourCustomClass : NSObject
@property (strong) NSString *title;

- (void)doSomethingWithTheTitle;
@end

@implementation ITYourCustomClass
- (void)doSomethingWithTheTitle {
    NSLog(@"Here's my title: %@", self.title);
}
@end

使用它

@implementation ITAppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    ITYourCustomClass *objectOfYourCustomClass = [[ITYourCustomClass alloc] init];
    [objectOfYourCustomClass doSomethingWithTheTitle];
}

@end

类和对象方法

使用+声明的方法,表示可以直接在一个类上调用这个方法,就像你使用[myClass1 setLabel:@"something"];一样。但是这没有意义,你想要创建一个属性。 属性被保存在对象中,所以你可以创建一个对象ITYourCustomClass *objectOfYourCustomClass = [[ITYourCustomClass alloc] init]; 并设置属性objectOfYourCustomClass.title = @"something"。然后你可以调用[objectOfYourCustomClass doSomethingWithTheTitle];,它是一个公共对象方法。


好的..我觉得我的+和-有些问题。我是Mac开发的新手,已经开发了2年的iPhone应用程序。我将Class1和Class2连接到两个不同的nib文件中,这些文件被加载,其中一个包含一个标签,另一个包含一个文本字段,我只想使用另一个窗口中的文本字段更改一个窗口中的标签。使用你给我的示例,我得到了与之前完全相同的结果:NSLog给我我的更改标题,但标签本身如果我从另一个类调用-doSomethingWithTheTitle不会改变。 - Vincent Friedrich
@VincentFriedrich 那么在Interface Builder中如何使用Class1和Class2呢?通常你会有一个视图控制器或窗口控制器来管理这些东西。或者你可以添加对象来连接它们,就像在初始nib文件中的AppDelegate类一样。 - IluTov
是的,我添加了一个对象并将其命名为“Class1”,并从那里管理所有内容。在windowController中我什么都不做...这是我第一次尝试制作Mac应用程序。我使用这个对象是因为在使用nsviewcontroller或windowcontroller时遇到了几个问题。 - Vincent Friedrich
你在IB中连接了文本框到outlet了吗? - IluTov
@VincentFriedrich,你有可能把它发布到Github上吗?这种错误真的很难找到。 - IluTov

0

您正在尝试使用类方法访问实例变量。您应该将+setLabel:方法转换为-setLabel:,并像这样调用它:

[_myClass1Variable setLabel:@"Test"];

此外,-setStringValue 是什么?如果你只是想改变 UILabel 的文本,你需要调用 -setText:

0

我猜 label 应该是一个 NSTextField,而你试图在没有加载 XIB 的情况下设置它的值,导致你的 awakeFromNib 没有被调用。因此,这个 outlet 将不会绑定到那个 label


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接