2011-04-23 32 views
1

我有一個通用的iOS應用程序,我一直在努力。大多數情況下,我一直通過創建子類來處理設備差異,因此RootViewController由RootViewController-iPad和RootViewController-iPhone分類。該模式開始在main.m文件,在那裏我做設備檢測如下:分配或初始化超類的子類

int retVal; 
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { 
    retVal = UIApplicationMain(argc, argv, nil, @"SalesPadAppDelegate_iPad"); 
} else { 
    retVal = UIApplicationMain(argc, argv, nil, @"SalesPadAppDelegate_iPhone"); 
} 

這種模式合作得非常好,而且是儘量減少代碼重用。

再往下看,我有一系列繼承自公共超類MasterDetailViewController的視圖控制器。這個超類需要一些設備特定的代碼,所以我在考慮子類化,然後結束於超類自動分配或實例化最適合的設備特定子類。

實現明智的,這看起來像以下:

+(id)allocWithZone:(NSZone *)zone { 
    if ([[self class] isEqual:[MasterDetailViewController_iPad class]] || [[self class] isEqual:[MasterDetailViewController_iPhone class]]) { 
     return [super allocWithZone:zone]; 
    } else { 
     if ([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPhone) { 
      return [MasterDetailViewController_iPhone allocWithZone:zone]; 
     } else { 
      return [MasterDetailViewController_iPad allocWithZone:zone]; 
     } 
    } 
} 

此代碼不能正常工作,而且是一種概念的示範。有沒有辦法做我想做的事情,還是我看到的事情都是錯的?

編輯:要清楚,超級和子類的數據是相同的。唯一的區別是幾個方法實現。這個想法是,子類比設備特定的意大利麪代碼更乾淨。

回答

1

機會是你的代碼不工作,因爲self裏面的類方法是類對象,所以[self class]的類。改爲嘗試[self isEqual:[MasterDetailViewController_iPad class]]。你還可以掉頭的比較,是這樣的:

+ (id)allocWithZone:(NSZone *)zone { 
    // Allocating a subclass, don't interfere 
    if (![self isEqual:[MasterDetailViewController class]]) { 
     return [super allocWithZone:zone]; 
    } 

    // Select an appropriate subclass to create instead 
    if ([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPhone) { 
     return [MasterDetailViewController_iPhone allocWithZone:zone]; 
    } else { 
     return [MasterDetailViewController_iPad allocWithZone:zone]; 
    } 
} 

這可能是更容易一些擴展,如果你有原因的更多特定於設備的子類。

請注意,還有其他方法可以做到這一點。例如,代替特定於設備的子類,一個通用類可以分配和使用設備特定的幫助對象來處理需要不同的少數操作(有點像委託)。或者,不要覆蓋allocWithZone :,你可以讓基類的init方法版本爲self,而是分配並返回適當子類的新對象。或者你可以使用工廠方法來分配適當的設備特定的子類。

+0

你對課堂問題是正確的,是一種頭腦發熱的錯誤。我最終只是進一步子分類鏈。 – jcnnghm 2011-05-18 02:26:05

+0

當試圖解決docs next advice中發現的類似問題時:「不要重寫allocWithZone:包含任何初始化代碼,而應該包含init ...方法的類特定版本。」 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/index.html#//apple_ref/occ/clm/NSObject/allocWithZone: – 2015-04-28 04:15:30