我正在看以下苹果示例源代码:
/*
Cache the formatter. Normally you would use one of the date formatter styles (such as NSDateFormatterShortStyle), but here we want a specific format that excludes seconds.
*/
static NSDateFormatter *dateFormatter = nil;
if (dateFormatter == nil) {
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"h:mm a"];
}
Run Code Online (Sandbox Code Playgroud)
试图找出:
为什么要使用static关键字?
如果在每次调用方法时将其设置为nil,这相当于缓存变量.
代码来自Tableview Suite演示中的示例4
好的,在C,C++,C#和Objective-C之间切换时仍然会重新调整,所以有时我的脑袋会旋转.然而,这一次,我对于正确的方式更加困惑,因为我已经看到至少有三种不同的方式在Objective-C中声明静态变量,如果你认为它只是C本身的超集,那就是第四种.那么这些是对的?
如果我们想要共享一个独立变量(即不是一个静态类变量,而是一个刚刚在头文件中定义的变量),那就像在'C'中那样(在标题中带有'extern'的ala)?
foo.h中
@interface Foo : NSObject{
static int Laa;
}
@end
Run Code Online (Sandbox Code Playgroud)
Foo.m
@implementation Foo
...
@end
Run Code Online (Sandbox Code Playgroud)
foo.h中
@interface Foo : NSObject{
}
@end
Run Code Online (Sandbox Code Playgroud)
Foo.m
static int Laa; // <-- Outside of the implementation
@implementation Foo
...
@end
Run Code Online (Sandbox Code Playgroud)
foo.h中
@interface Foo : NSObject{
}
@end
Run Code Online (Sandbox Code Playgroud)
Foo.m
int Laa; // <-- Note no word 'static' here like in 'Option B'
@implementation Foo
...
@end
Run Code Online (Sandbox Code Playgroud)
foo.h中
static int Laa;
@interface Foo : NSObject{
}
@end
Run Code Online (Sandbox Code Playgroud)
Foo.m
@implementation …Run Code Online (Sandbox Code Playgroud) 尽管有关该主题的许多主题,我仍然不清楚何时选择哪种方法.我希望通过讨论一个具体的例子,我终于"明白了".
注意:我的语言是Cocoa,尽管一般问题不是语言特定的.
我有一个类TaskQueue,我想用它:
首次使用TaskQueue时,我希望TaskQueue启动一个线程,然后定期唤醒该线程来处理任务.
显然,我至少需要两个变量:
由于我只需要一个任务队列和一个线程来处理这些任务,我有两个选择:
做任务队列一个单独的类(如描述例如使用CWL_DECLARE_SINGLETON_FOR_CLASS_WITH_ACCESSOR http://www.cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html,我相信我将不得不修改CWLSynthesizeSingleton. h文件在初始化时启动线程.)
让任务数组和线程实例都是静态的(遵循这里建议的方法:如何在Objective-C中声明类级属性?)
在这个特定情况下,是否有一种方法比另一种方法更好?如果是这样,为什么?
目前我在AppDelegate类上使用了一个Property.
现在,随着我的需求消耗,我需要更多的这些全局属性,所以我想创建一个Singleton类,它将保存属性并将管理它们.我发现了很多关于单身人士的信息,但我无法弄清楚,是否有可能在没有班级实例的情况下修改该属性?
例如:
@interface Tools : NSObject
@property (nonatomic,retain) NSDictionary* item;
...
@end
Run Code Online (Sandbox Code Playgroud)
我想要做:
[Tools setItem:someDict];
someClass = [someClass alloc] initWithItem:[Tools getItem]];
Run Code Online (Sandbox Code Playgroud)
我的所有想法最终都遇到了类Tools没有实例的问题.我已经尝试将项目设置为静态变量(不是属性),这有效,但我确信这不是正确的原因.
相关但不同的问题,添加:
#import "Tools.h"
Run Code Online (Sandbox Code Playgroud)
对于项目-Prefix.pch文件,所以项目属性将从项目的任何地方可用,是个好主意?
我需要一个常量的字符串数组.使用#define是个好主意?
例如:
#define rows [NSArray arrayWithObjects: @"NameRowA",@"NameRowB",@"NameRowC", nil]
#define KEY_ROWA [columnas objectAtIndex:0]
#define KEY_ROWB [columnas objectAtIndex:1]
#define KEY_ROWC [columnas objectAtIndex:2]
Run Code Online (Sandbox Code Playgroud)
我需要访问字符串数组和该数组的元素.
我已经读过了,(我不知道是不是真的)用这种方式创建一个新的NSArray,当它被使用时,我想这个数组已经发布了,所以我认为这很好,因为你只使用那部分内存什么时候需要它.
我想在Cocoa中有一个静态变量.
看看如何在Objective-C中声明类级属性?,我不清楚到目前为止我所做的事情是否有任何问题,即
// Foo.m
static NSString* id;
@interface Foo ()
Run Code Online (Sandbox Code Playgroud)
代替
// Foo.h
@interface Foo {
}
+(NSString*) id;
// Foo.m
+(NSString*) id
{
static NSString* fooId = nil;
if (fooId == nil)
{
// create id
}
return fooId;
}
Run Code Online (Sandbox Code Playgroud)
显然,第二种方法提供了初始化id的机会.但是,如果我自己在代码中的其他地方初始化id,在一个getter中说:
-(NSString*) getId
{
if (id==nil) {
id = ... // init goes here
}
return id;
}
Run Code Online (Sandbox Code Playgroud)
那么简单的静态声明方法与更复杂的类函数方法相比有什么不对吗?我错过了什么?