我仍然在尝试在面向对象的世界中应该如何做事情,我想我的问题是我不知道如何最好地利用封装。具体地说,我在项目中的几个类中使用了大量的小代码。例如:
+ (NSString *)getFormattedDate;
+ (NSString *)getResultsFilePath;
+ (NSError *)removeFileFromCache:(NSString *)fileName;这些都是我在多个类中使用的3-5行方法。我的标准做法是将这些代码片段放到一个Utility.inc文件中,并在需要时调用它们。这在面向对象的世界中合适吗?或者每个类都应该是自包含的?如果合适的话,你会把代码放到一个单例中,还是只放在一个常规的类文件中,并在你想要使用这些方法的每个类中放入[Utilities alloc init]?
发布于 2012-03-22 01:32:24
谢谢你的回答。我不确定这是不是正确的方法,但这就是我在刚刚提交的项目中所做的。
我创建了两个类,一个用于Utility方法,另一个用于全局变量。Utilities类中的方法都是类方法,因为它们对文件和常量或全局变量进行操作。然后我为全局变量创建了一个单例。我的所有全局常量都在.pch文件中。另外,在.pch文件中,我放入了以下两行代码,以便实用程序和全局变量随处可用。
// File for utilities like file delete, find Documents file
#import "Utilities.h"
#import "Globals.h"访问这些方法很简单。下面是调用这两种方法为电子邮件生成HTML标头的示例。
NSString *gameNameHeader = [NSString stringWithFormat:@"<p> </p><h1>%@ Results</h1><h2>%@%@</h2>",GAME_NAME_TITLE,[Utilities formattedClientName], [Utilities formattedDate]];如果任何人都可以使用它,这是我当前版本的代码。(抱歉的格式-我似乎不能让维基合作。)
@interface Utilities : NSObject {
}
+ (NSString *)formattedDate;
+ (NSString *)formattedClientName;
+ (NSString *)cachedResultsFilePath;
+ (NSString *)cachedResultsFileContents;
+ (NSString *)resultsFileName;
+ (NSError *)removeFileFromCache:(NSString *)fileName;
+ (NSString *)applicationCachesDirectory;
+ (NSString *)applicationDocumentsDirectory;
+ (NSString *)applicationLibraryDirectory;
+ (NSError *)copyCachedResultsToFile;
@end
#import "Utilities.h"
@implementation Utilities {
}
+ (NSString *)formattedDate {
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSString *todaysDate = [dateFormatter stringFromDate:[NSDate date]];
return todaysDate;
}
+ (NSString *)formattedClientName {
NSString *client = [NSString stringWithFormat:@" "];
if( [Globals sharedInstance].currentClient ) client = [NSString stringWithFormat:@" %@ ",[Globals sharedInstance].currentClient];
return client;
}
+ (NSString *)cachedResultsFilePath {
NSString *resultsFilePath = [[self applicationCachesDirectory] stringByAppendingPathComponent:@"Results.txt"];
return resultsFilePath;
}
+ (NSString *)cachedResultsFileContents {
NSStringEncoding encoding; NSError* error = nil;
NSString *resultsText = [NSString stringWithContentsOfFile:[self cachedResultsFilePath] usedEncoding:&encoding error:&error];
return resultsText;
}
+ (NSString *)resultsFileName {
return [NSString stringWithFormat:@"%@ Results%@%@.html",GAME_NAME_TITLE,[self formattedClientName],[self formattedDate] ];
}
+ (NSError *)removeFileFromCache:(NSString *)fileName {
NSError *error = nil;
NSFileManager *localFileManager=[[NSFileManager alloc] init];
NSString *fullPath = [NSString stringWithFormat:@"%@/%@", [self applicationCachesDirectory],fileName];
[localFileManager removeItemAtPath: fullPath error:&error ];
return error;
}
+ (NSString *)applicationCachesDirectory {
return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
}
+ (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
+ (NSString *)applicationLibraryDirectory {
return [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
}
+ (NSError *)copyCachedResultsToFile {
// Grab the header and footer and put it around the cached data
NSStringEncoding encoding; NSError *error = nil;
NSString *htmlHeaderTextPath = [[NSBundle mainBundle] pathForResource:@"HTML_header" ofType:@"html" ];
NSString *htmlHeaderText = [NSString stringWithContentsOfFile:htmlHeaderTextPath usedEncoding:&encoding error:&error];
NSString *cachedResultsText = [NSString stringWithContentsOfFile:[self cachedResultsFilePath] usedEncoding:&encoding error:&error];
// Write the results to a file if there are any
if (cachedResultsText) {
NSString *htmlFooterTextPath = [[NSBundle mainBundle] pathForResource:@"HTML_footer" ofType:@"html" ];
NSString *htmlFooterText = [NSString stringWithContentsOfFile:htmlFooterTextPath usedEncoding:&encoding error:&error];
NSString *gameNameHeader = [NSString stringWithFormat:@"<h1>%@ Results for%@%@</h1>",GAME_NAME_TITLE,[self formattedClientName],[self formattedDate] ];
NSString *tempStringP1 = [htmlHeaderText stringByAppendingString:gameNameHeader];
NSString *tempStringP2 = [tempStringP1 stringByAppendingString:cachedResultsText];
NSString *formattedTextForPrinting = [tempStringP2 stringByAppendingString:htmlFooterText];
NSString *resultsFilePath = [ [Utilities applicationDocumentsDirectory] stringByAppendingPathComponent:[self resultsFileName] ];
if ( !([[NSFileManager defaultManager] fileExistsAtPath:resultsFilePath]) ) {
if (! ([[NSFileManager defaultManager] createFileAtPath:resultsFilePath contents:nil attributes:nil]) ) {
NSLog(@"Error was code: %d - message: %s", errno, strerror(errno));
}
}
NSFileHandle *fileHandler = [NSFileHandle fileHandleForUpdatingAtPath:resultsFilePath];
[fileHandler writeData:[formattedTextForPrinting dataUsingEncoding:NSUTF8StringEncoding]];
[fileHandler closeFile];
}
return error;
}
@end单例中的全局变量。可能不是线程安全的,但我现在并不关心。
@interface Globals : NSObject {
}
@property (nonatomic, strong) NSString *currentClient;
@property (nonatomic, strong) NSString *showmePict;
@property BOOL checkBoxes;
+ (Globals *)sharedInstance;
- (void)resetClient;
@end@实现全局变量{
}
static Globals *singleton = nil;
@synthesize currentClient = _currentClient;
@synthesize showmePict = _showmePict;
@synthesize checkBoxes = _checkBoxes;
+(Globals *) sharedInstance {
NSLog (@"sharedInstance of Globals called.");
if (nil != singleton) return singleton;
static dispatch_once_t pred; // lock
dispatch_once(&pred, ^{ // this code is at most once
singleton = [[Globals alloc] init];
});
return singleton;
}
- (void)resetClient {
self.currentClient = nil;
}
@end发布于 2012-03-13 04:01:50
研究一下如何使用Categories。对于您给出的示例,这些都是与某个特定类的对象相关的方法,这些对象恰好在您自己的几个类中使用。类别将允许您将这些常用方法放在与公共因素相关联的位置。
发布于 2012-03-13 03:59:23
创建一个utitity singelton,它将只创建一个类,然后被其他类使用。
https://stackoverflow.com/questions/9673893
复制相似问题