Iphone 使用NSUserDefaults作为某种全局实例变量是个坏主意吗?

Iphone 使用NSUserDefaults作为某种全局实例变量是个坏主意吗?,iphone,objective-c,ipad,Iphone,Objective C,Ipad,我有一个应用程序,当主主屏幕加载时,我会在后台检查同步更新。如果连接速度慢,或者用户在应用程序中移动速度快,这些请求可能会堆积在后台。为了防止出现这种情况,我想实现一个BOOL变量,通过切换YES或NO来防止多个请求进行同步检查 因此,当启动请求时,我的代码如下所示: NSUserDefaults *d = [NSUserDefaults standardUserDefaults]; NSString *key = [NSString stringWithFormat:kVarAllowSy

我有一个应用程序,当主主屏幕加载时,我会在后台检查同步更新。如果连接速度慢,或者用户在应用程序中移动速度快,这些请求可能会堆积在后台。为了防止出现这种情况,我想实现一个BOOL变量,通过切换YES或NO来防止多个请求进行同步检查

因此,当启动请求时,我的代码如下所示:

 NSUserDefaults *d = [NSUserDefaults standardUserDefaults];
 NSString *key = [NSString stringWithFormat:kVarAllowSyncRequest, aManufacturerID];
 [d setBool:NO forKey:key];
我知道这会起作用,但在我的应用程序使用期间,这会被称为100次-这是我甚至需要担心的事情吗

有更好的方法吗?

是的,速度会很慢

要么放入AppDelegate,要么为其创建一个单例

NSUserDefaults
应用于保存通常不会经常更改的值

最容易实现的全局变量解决方案是将属性添加到您已经可以使用的singleton类——您的应用程序委托!以下是我通常使用的需要经常访问应用程序委托的视图中控制器的代码:

// read-only property to return my app delegate
- (MyAppDelegate*)appDelegate {
return (MyAppDelegate*)[[UIApplication sharedApplication] delegate] ;
}
然后,假设您的应用程序代理上有一个
allowSyncRequest
属性,您可以通过以下方式从视图控制器访问它:

self.appDelegate.allowSyncRequest = NO;

用户默认设置是放置首选项和信息的好地方,这些首选项和信息在每次会话中不会更改或需要访问两到三次以上。访问默认值意味着点击磁盘,速度很慢;你不想用它来做一些事情,比如一分钟检查很多次旗子

应用程序委托是存储应用程序中许多对象真正需要访问的信息的方便地方,因为它始终可以通过
[[UIApplication sharedApplication]委托]
访问,但你应该仔细考虑你的应用程序设计,然后用很多IVAR来衡量这个对象,仅仅因为它看起来很方便

大概只有一个对象,可能是视图控制器,负责发送这些请求。那是挂国旗的地方。根据您的描述,听起来您根本不需要应用程序全局变量。该标志仅由发起请求的对象使用,因此它是唯一需要了解该标志的对象。该标志可以是ivar

事实上,如果您有一个类,该类可能有许多实例,每个实例都将发送一个请求,那么正确的解决方案是拥有一个任何实例都可以访问的类级别标志。这很简单。在实现文件中,声明一个变量以保存标志:

// RequestMaker.m

#import "RequestMaker.h"

static BOOL allowSyncRequest = YES;

@implementation RequestMaker
// etc.
它被声明为
static
,以使其仅在这个“编译单元”中可见(松散地说,在这个文件中)

然后创建一个类方法来设置和获取此标志:

+ (BOOL) allowSyncRequest {
    return allowSyncRequest;
}

+ (void) setAllowSyncRequest: (BOOL)b {
    allowSyncRequest = b;
}
现在,每当您的
RequestMaker
实例想要启动请求时,它都应该检查标志;如果是
YES
,则可以关闭该标志并启动请求。您还需要确保在请求完成时重置标志

(所有这些都假设您没有为请求显式地处理不同的线程。如果是,那么您应该研究信号量,也许还有信号量。即使您不想使用GCD,也有一组非常好的方法可以让阅读变得有趣。)