【问题标题】:Category on NSObject to get instance of AppDelegate?NSObject 上的类别以获取 AppDelegate 的实例?
【发布时间】:2012-05-01 03:32:57
【问题描述】:

我需要经常访问我的核心数据托管对象上下文,而不是每次在每个类中获取[[UIApplication sharedApplication] delegate] 的实例并将其存储在一个变量中,我想知道这样做是否可以:

@interface NSObject(DelegateExtension)
- (AppDelegate*)appDelegate;
@end

@implementation 
NSObject(DelegateExtension)
- (AppDelegate*)appDelegate
{
    return (AppDelegate*)[[UIApplication sharedApplication] delegate];
}
@end

所以我可以在我的代码中的任何地方执行self.appDelegate

这样做有什么问题吗?这是不好的编程习惯吗?

【问题讨论】:

标签: objective-c ios cocoa-touch


【解决方案1】:

或者,您可以将预处理器宏(或静态 C 函数)添加到您的 Prefix.pch 文件中:

#define AppDelegateInstance() (AppDelegate *)[[UIApplication sharedApplication] delegate]

这将使您的应用委托可以从代码中的任何位置访问,并且不会与任何名为 appDelegate 的现有方法发生冲突。

【讨论】:

  • 要使用,您只需在要访问应用程序委托实例的任何地方键入AppDelegateInstance()。预处理器会在编译前将其替换为(AppDelegate *)[[UIApplication sharedApplication] delegate]
  • 但是我想知道你还能用宏访问属性吗?
  • 是的。如果您的应用程序委托有一个名为 foo 的属性,您应该仍然可以使用 [AppDelegateInstance() foo] 访问它,它将扩展为 [(AppDelegate *)[[UIApplication sharedApplication] delegate] foo]
  • 优秀,+1。我会使用常量头文件,但前缀似乎更合适和有效。
  • @CameronSpickert : 这个方法工作得很好。考虑如果我们必须更改 appdelegate 属性 foo 的值,该怎么做..?
【解决方案2】:

我通常使用全局变量来指向应用程序委托。

在 MyAppDelegate.h 中:

extern MyAppDelegate* AppDelegate;

在 MyAppDelegate.m 中:

MyAppDelegate* AppDelegate = nil;

- (id)init {
    if (self = [super init]) {
        AppDelegate = self;
        …
    }
}

现在任何导入“MyAppDelegate.h”的人都可以使用AppDelegate 变量来访问您的应用委托。

【讨论】:

  • 哦,太好了..在声明中添加static 会有什么影响?
  • static 限制了声明所在文件的可见性——这与您的需求背道而驰。
  • 我收到此错误:Undefined symbols for architecture i386: "_appDelegate", referenced from: -[AppDelegate application:didFinishLaunchingWithOptions:] in AppDelegate.o
  • 我在 applicationDidFinishLaunching 中设置了 appDelegate = self
  • 设置断点。如果它真的被调用了两次,堆栈跟踪会告诉你原因。
【解决方案3】:

NSObjectUIApplication 或其代表没有任何有意义的联系。从设计的角度来看,我认为这样做是一种糟糕的黑客行为。还有其他三个我认为会好几百万倍的解决方案:

  1. 函数,它的声明在一个由你的前缀头导入的头中。

  2. UIApplication 上的类别,这实际上是一个与您尝试执行的操作有关的类别。

  3. 全局指针,如 OS X* 上的 NSApp,在程序中首先设置为指向 UIApplication 实例。

  4. (四种解决方案!)指向应用委托的全局指针。

有关实施 3 或 4 的信息,请参阅 On lazy instantiation and convenience methods


*真的不明白他们为什么不在 iOS 上这样做。

【讨论】:

  • @mohabitar:我添加了一个指向我的答案的链接,我认为它会给你这个想法。如果您需要更多信息,请告诉我,我会扩展。有趣的问题,顺便说一句。
【解决方案4】:

当然是安全的,只要您知道苹果在不久的将来不会或不会有一个名为 appDelegate 的方法。子类化是首选方法,尤其是因为 NSObject 是一个根类。但是,这需要课堂摆姿势,这在 OSX 10.5+ 中已完全弃用,甚至在 iOS 设备上也不是可行的选择。

【讨论】:

    猜你喜欢
    • 2014-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多