xcode 没有接口生成器的可可,初始化应用程序控制器的实例?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/622998/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cocoa without Interface Builder, initialize an instance of app controller?
提问by cemulate
I don'tplan to write applications without IB, I'm just in the process of trying to learn more about programming.
我不打算在没有 IB 的情况下编写应用程序,我只是在尝试学习更多有关编程的知识。
How can I get a single instance of my AppController class at startup? (It's normally loaded from the nib.) And can you clear up the use of +initialize
and -init
? If I understand, +initialize
is called on all classes at startup. How can I use this to create an instance of my AppController with instance variables that make up my interface?
如何在启动时获取 AppController 类的单个实例?(它通常是从笔尖加载的。)你能弄清楚+initialize
and的用法-init
吗?如果我理解,+initialize
在启动时调用所有类。我如何使用它来创建我的 AppController 的实例,其中包含构成我的界面的实例变量?
Hope that makes sense, and thanks for any help.
希望这是有道理的,并感谢您的帮助。
回答by Peter Hosey
+initalize
is sent to a class the first time it or one of its subclasses receives a message for the first time. So, when you do:
+initalize
在类或其子类第一次收到消息时发送给该类。所以,当你这样做时:
instance = [[[YourClass alloc] init] autorelease];
That alloc
message triggers initialize
.
该alloc
消息触发initialize
。
If you do the same thing with a subclass:
如果你对一个子类做同样的事情:
instance = [[[SubclassOfYourClass alloc] init] autorelease];
That alloc
message will trigger +[YourClass initialize]
the same way the other one did (prior to also triggering +[SubclassOfYourClass initialize]
. But only one of these will do it—each class's initialize
never gets called more than once. (Unless you call it yourself with [super initialize]
or [SomeClass initialize]
—so don't do that, because the method won't be expecting it.)
该alloc
消息将以+[YourClass initialize]
与另一个相同的方式触发(在也触发 之前+[SubclassOfYourClass initialize]
。但只有其中一个会这样做——每个类initialize
永远不会被调用一次以上。(除非你自己用[super initialize]
or调用它——所以[SomeClass initialize]
不要那样做,因为该方法不会期待它。)
-init
, on the other hand, initializes a new instance. In the expression [[YourClass alloc] init]
, you are personally sending the message directly to the instance. You may also call it indirectly, through another initializer ([[YourClass alloc] initWithSomethingElse:bar]
) or a convenience factory ([YourClass instance]
).
-init
,另一方面,初始化一个新实例。在表达式中[[YourClass alloc] init]
,您亲自将消息直接发送到实例。您也可以通过另一个初始化程序 ( [[YourClass alloc] initWithSomethingElse:bar]
) 或便利工厂 ( [YourClass instance]
)间接调用它。
Unlike initialize
, you should always send init
(or another initializer, if appropriate) to your superclass. Most init methods look roughly like this:
与 不同initialize
,您应该始终将init
(或其他初始化程序,如果合适)发送到您的超类。大多数 init 方法大致如下所示:
- (id) init {
if ((self = [super init])) {
framistan = [[Framistan alloc] init];
}
return self;
}
Details differ (this method or the superclass's or both may take arguments, and some people prefer self = [super init]
on its own line, and Wil Shipley doesn't assign to self
at all), but the basic idea is the same: call [super init[WithSomething:…]]
, make sure it didn't return nil
, set up the instance if it didn't, and return whatever the superclass returned.
细节上有所不同(此方法或超类的或双方可以采取的论点,有的人喜欢self = [super init]
在自己的路线,和威尔·希普利不分配给self
所有),但基本思路是一样的:调用[super init[WithSomething:…]]
,确保它没” t return nil
,如果没有,则设置实例,并返回超类返回的任何内容。
This implies that youcan return nil
from init
, and indeed you can. If you do this, you should [self release]
, so that you don't leak the failed object. (For detecting invalid argument values, an alternative is NSParameterAssert
, which throws an exception if the assertion fails. The relative merits of each are beyond the scope of this question.)
这意味着您可以nil
从返回init
,并且确实可以。如果你这样做,你应该[self release]
这样做,这样你就不会泄漏失败的对象。(为了检测无效的参数值,另一种方法是NSParameterAssert
,如果断言失败,它会抛出异常。每个的相对优点超出了这个问题的范围。)
How can I use this to create an instance of my AppController with instance variables that make up my interface?
我如何使用它来创建我的 AppController 的实例,其中包含构成我的界面的实例变量?
The best way is to do it all in main
:
最好的方法是做到这一切main
:
int main(int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
AppController *controller = [[[AppController alloc] init] autorelease];
[[NSApplication sharedApplication] setDelegate:controller]; //Assuming you want it as your app delegate, which is likely
int status = NSApplicationMain(argc, argv);
[pool drain];
return status;
}
You'll do any other set-up in your application delegate methods in AppController
.
您将在AppController
.
You already know this, but for anyone else who reads this: Nibs are your friend. Interface Builder is your friend. Don't fight the framework—work with it, and build your interface graphically, and your application will be better for it.
您已经知道这一点,但对于其他阅读本文的人来说:笔尖是您的朋友。Interface Builder 是您的朋友。不要与框架抗争——使用它,并以图形方式构建您的界面,您的应用程序将因此变得更好。
回答by greggT
A set of NIBs seem to be an unsatisfactory answer, even when represented in XML (as a XIB), because there's no easy way to compare or merge them with any standard subversion or SCM-style tool. The encoded information is fragile and not intended to be edited by mere humans. How would changes be represented by a GUI? Would I step through each attribute of each control and visually check them?
一组 NIB 似乎是一个不能令人满意的答案,即使以 XML(作为 XIB)表示,因为没有简单的方法可以将它们与任何标准 subversion 或 SCM 样式的工具进行比较或合并。编码的信息是脆弱的,不能由人类编辑。GUI 将如何表示更改?我会遍历每个控件的每个属性并目视检查它们吗?
If the app's behavior is written in code, however, there is a chance that I can figure out what's going in, even if I have to keep lots of details close at hand at the same time.
但是,如果应用程序的行为是用代码编写的,我就有可能弄清楚发生了什么,即使我必须同时掌握大量细节。
A proposedsolution: use a top-level NIB that the main architect coded up, but then code the rest of the app explicitly.
一个提出的解决方案:使用一个顶级NIB的主要设计师编码,但后来明确地编写应用程序的其余部分。
Anybody got a better idea?
有人有更好的主意吗?
回答by greggT
Another solution to the problem of launching an app without a nib.
没有笔尖启动应用程序问题的另一种解决方案。
Instead of allocing your own controller, just use the extra parameters in the NSApplicationMain()
method:
无需分配您自己的控制器,只需在NSApplicationMain()
方法中使用额外的参数即可:
int retVal = NSApplicationMain(argc, argv, @"UIApplication", @"MyAppDelegate");
This takes care of all the proper linking one would need.
这会处理所有需要的正确链接。
Then, the only other thing you'd need to remember is to make your own window and set it to visible.
然后,您唯一需要记住的另一件事是创建自己的窗口并将其设置为可见。