2011-06-02 57 views
0

我在Objective-C中編寫一個方法使對象爲零時遇到了一些麻煩。下面是一些例子:Objective-C方法使對象無效

@interface testA : NSObject 
{ 
    NSString *a; 
} 

@property (nonatomic, retain) NSString *a; 

+(testA*)initWithA:(NSString *)aString; 

-(void)displayA; 
-(void)nillify; 
@end 

@implementation testA 
@synthesize a; 
+(testA*)initWithA:(NSString *)aString{ 
    testA *tst=[[testA alloc] init]; 
    tst.a=aString; 
    return [tst autorelease]; 
} 
-(void)displayA{ 
    NSLog(@"%@",self.a);  
} 
-(void)nillify{ 
    self=nil; 
} 
- (void)dealloc { 
    [a release]; 
    [super dealloc]; 
} 
@end 

int main(int argc, char **argv){ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    testA *test=[testA initWithA:@"some test"]; 
    [test displayA]; 
    test=nil; 
    //[test nillify]; 

    NSLog(@"after setting to nil"); 

    [test displayA]; 
    [pool release]; 
    return 0; 
} 

顯然,當我設置的測試對象爲nil,然後調用它的一些方法,什麼都不會發生,但如果我不是調用它直接設置爲nil,nillify,displayA法正常工作,像測試對象仍然存在。有沒有一種解決方法讓nillify方法正常工作?

非常感謝您的幫助!

回答

4

你不能這樣做,因爲將'self'設置爲nil只會在該方法的範圍內產生任何效果(在你的情況下,'nilify')。例如,您沒有任何實際的方法來影響位於堆棧其他部分或堆中隨機位置的指針值。

基本上任何持有對某個對象的引用的代碼都負責維護和清除這些引用本身。如果你有一些用例,隨機代碼段可能需要引用某種「實時」對象,但是你希望這些對象引用響應某些外部事件而消失(可能是用戶跟蹤系統或其他) ,你可以通過通知來做一些事情,但是跟蹤這些「實時」對象的各種模塊仍然負責在收到通知時收聽通知並清理引用。

然而,'化學'的東西不可能工作。

2

你不能做你想做的事情。 self僅僅是對其他地方實際存在的對象的本地引用。將它設置爲nil並不意味着什麼。一般來說,一個對象本身並不擁有,它當然不能控制其他對象對它的引用。管理其壽命取決於擁有的對象。

1

你的代碼有幾個錯誤。

首先,按照慣例,類名以大寫字母開頭。請遵守這些命名約定,因爲這會使其他開發人員更難使用您的代碼(甚至會讓您感到困惑)。

接下來,您的initWithName: ...根據命名約定,名稱中包含init的方法應該是實例方法,而不是類方法。因此,無論它命名爲newWithName:或把它變成一個實例方法是這樣的:

-(testA*)initWithA:(NSString *)aString{ 
    self = [super init]; 
    if (!self) return nil; 
    tst.a=aString; 
    return self; 
} 

如果你把它當作類方法(並將其命名爲newWithName:),你應該返回根據命名規則,因爲一個自動釋放的對象以init...new...開頭的方法返回保留的對象。如果你不遵守這些慣例,靜態分析儀會給你「錯誤」的警告,它將變得毫無用處。

現在爲什麼你的nillify不起作用:self實際上是一個論點一個方法。在引擎蓋下,你的nillify方法實際上有兩個你看不到的參數:self指針和選擇器指針。這意味着,self實際上是堆棧上的一個變量。如果您覆蓋它,您只覆蓋該堆棧變量,但不會影響您在其他位置的變量test

作爲示例,考慮方法- (void)foo:(NSString *)bar;。編譯器將其變成等效的C函數(void) foo(id self, SEL _cmd, NSString *bar)