2012-03-12 66 views
0

我仍然试图围绕如何在面向对象的世界做事情,我认为我的问题是我不明白如何最好地利用封装。具体来说,我在我的项目的几个类中使用了大量的小代码。例如:在应用中跨类共享方法的最佳做法是什么?

+ (NSString *)getFormattedDate; 
+ (NSString *)getResultsFilePath; 
+ (NSError *)removeFileFromCache:(NSString *)fileName; 

这些是我在多个类中使用的所有3-5行方法。我的标准做法是将这些片段放入Utility.inc文件中,并在需要时调用它们。这在面向对象的世界中是否合适?或者每个类是否应该是独立的?如果合适,你会把代码放到一个单例中,或者只是一个普通的类文件和每个想要使用这些方法的类中的[[Utilities alloc] init]?

+3

你能在什么这些方法做详细点吗?他们有一些内部状态吗?从名称猜测,'getFormattedDate'和'getResultsFilePath'可能是函数而不是方法(不与类关联)。 – 2012-03-12 20:12:27

+0

我不确定术语,但我认为Obj-C中的所有'函数'都被称为方法。这些都是类方法,他们要么对文件做些什么,例如删除录音或创建电子邮件文件,或返回字符串,例如Cache目录的位置。这些效用方法都不需要知道项目中的任何对象。 – JScarry 2012-03-13 16:22:13

+0

不,函数和方法非常相似,但是方法属于一个类,并且对类的数据进行操作具有重要的区别。一般来说,如果一个“过程”(在这种情况下我们可以用作通用术语,涵盖方法和函数)不需要对类的数据进行操作,那么它可能更适合作为“简单”函数。这看起来与“平淡”的C相同。 – 2012-03-13 17:28:59

回答

0

感谢您的答案。我不确定这是否是正确的做法,但这是我刚刚提交的项目所做的。

我做了两个类,一个用于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>&nbsp</p><h1>%@ Results</h1><h2>%@%@</h2>",GAME_NAME_TITLE,[Utilities formattedClientName], [Utilities formattedDate]]; 

如果任何人可以使用它,这里是我的当前版本的代码。 (对不起格式化 - 我似乎无法与wiki进行合作。)

@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 

@implementation全局{

}

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 
0

创建一个纯粹的singelton,它只会被创建,然后被其他类使用。

2

看看使用Categories。对于你给出的例子,这些方法是与一些特定类的对象相关的,这些对象恰好在你自己的几个类中使用。类别将允许您将这些经常使用的方法放置在与常见因素相关的地方。

相关问题