2012-03-12 103 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。對於你給出的例子,這些方法是與一些特定類的對象相關的,這些對象恰好在你自己的幾個類中使用。類別將允許您將這些經常使用的方法放置在與常見因素相關的地方。

相關問題