2011-01-12 42 views
5

基本上,我有以下代碼(在這裏解釋:Objective-C Constants in ProtocolObjective-C覆蓋[NSObject初始化]是否安全?

// MyProtocol.m 
const NSString *MYPROTOCOL_SIZE; 
const NSString *MYPROTOCOL_BOUNDS; 

@implementation NSObject(initializeConstantVariables) 

+(void) initialize { 
    if (self == [NSObject class]) 
    { 
     NSString **str = (NSString **)&MYPROTOCOL_SIZE; 
     *str = [[MyClass someStringLoadedFromAFile] stringByAppendingString:@"size"]; 
     str = (NSString **)&MYPROTOCOL_BOUNDS; 
     *str = [[MyClass someStringLoadedFromAFile] stringByAppendingString:@"bounds"]; 
    } 
} 

@end 

我在想:是不是安全的,讓我有重寫NSObject的的+initialize方法的類?

+0

首先,您不需要創建一個類別讓運行時調用您的「初始化」,它會在發送任何消息之前自動執行。其次,「安全」是什麼意思?有沒有人閱讀文檔? – 2011-01-12 12:47:46

+0

看看類別...它覆蓋了NSObject類,而不是我的類。我正在嘗試使用我正在製作的框架的任何程序的開始時都會調用我知道的方法。 – 2011-01-12 12:51:25

回答

14

總之,不,你不能安全地在類的類別上實現+initialize方法。如果有的話,你最終會替換現有的實現,並且如果一個類的兩個類別都實現了+initialize,那麼不能保證它將被執行。

+load具有更可預測和明確定義的行爲,但發生得太早無法做任何有用的事情,因爲很多事情都處於未初始化狀態。

就我個人而言,我總共跳過+load+initialize,並使用編譯器註釋來導致基礎二進制/ dylib加載時執行函數。儘管如此,你當時可以安全地做的很少。

__attribute__((constructor)) 
static void MySuperEarlyInitialization() {...} 

爲了響應應用程序的啓動,您最好做好初始化工作。 NSApplicationUIApplication都提供委託/通知掛鉤,用於在啓動時嚮應用程序注入一些代碼。

0

NSString *const類型的變量您的代碼運行之前,總是會被初始化,假設我們忽略了C++變幻莫測的時刻:

NSString *const MY_PROTOCOL_SIZE = @"..."; 

const NSString *型(const關鍵字應用到NSString膽量的變量,而不是它的地址)可以被任何代碼修改,但不能有消息發送給它。它擊敗了它的目的const。考慮而不是全局函數:

static NSString *GetMyProtocolSize(void) { 
    return [[MyClass someStringLoadedFromAFile] ...]; 
} 

或者使用一個類的方法:

@implementation MyClass 
+ (NSString *)myProtocolSize { 
    return [[MyClass someStringLoadedFromAFile] ...]; 
} 
@end 

你問了一個問題更早,爲什麼你const字符串不會接受動態值 - 這是因爲你不似乎明白const對符號的作用。您應該閱讀C中const關鍵字的含義,如果const不是正確的,應該考慮另一種獲取字符串的方法。

2

爲什麼不在你的類MyClass中設置這兩個變量呢?而且,爲什麼不使用訪問器?我們最好在一個實際使用它的類上定義一個訪問器,而不是有一個來自無處不在的假常量變量。一個簡單的+(NSString *)myProtocolSize;即使在協議中也會做得很好。

此外,覆蓋類別「工作」中的類的方法,但不可靠,應該不惜代價避免:如果您覆蓋的方法在類別中實現,則運行時不保證加載訂單和您的實施可能永遠不會被添加到它。

+0

實際上,有20多個常量,創建一個類真是無法稱謂。 – 2011-01-12 13:46:28