2012-01-12 5 views
0

Пожалуйста, взгляните на эти два простых фрагмента кода. ЭтоUIImage преобразует в NSData таинственно

- (void)testMethod 
{ 

NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"myEncodedObjectKey"]; 
self   = (Profile *) [NSKeyedUnarchiver unarchiveObjectWithData:data]; 

for (int i = 0; i < self.avatar.count; i++) 
    [self.avatar replaceObjectAtIndex:i withObject:[UIImage imageWithData:[self.avatar objectAtIndex:i]]]; 

if ([[self.avatar objectAtIndex:0] isKindOfClass:[UIImage class]]) 
    NSLog(@"UIImage");//at this moment it's UIImage 
} 

и это:

[currentProfile testMethod]; 

if ([[currentProfile.avatar objectAtIndex:0] isKindOfClass:[NSData class]]) 
    NSLog(@"NSData");//Moment later it is NSData 

В первом я выборки пользовательского объекта из NSUserDefaults и работать с переменной NSMutableArray под названием «аватар». Я конвертирую каждый свой объект из NSData в UIImage. Тогда я проверю, что у меня есть, используя NSLog. Это UIImage. На втором фрагменте кода вы можете увидеть, как через мгновение UIImage вернется к NSData по своей воле. Похоже, я четко описал свою проблему. Вы понимаете, что происходит? Я не. Большое спасибо за внимание за ваше внимание.

ответ

2

Почему вы меняете свой объект в своем методе -testMethod? Это крайне незаконно.

Что вы на самом деле делаете, это установить локальную переменную self, которая передается как параметр вашего метода, в новое значение. Это означает, что вы не редактируете приемник метода, вы просто редактируете свой параметр.

Когда метод вызывается во время выполнения функции C objc_msgSend() называется:

// Declaration of objc_msgSend 
id objc_msgSend(id receiver, SEL selector, ...); 

Теперь, когда вы называете метод ...

[myInst testMethod]; 

... это то, что на самом деле вызывается во время выполнения:

objc_msgSend(myInst, @selector(testMethod)); 

Вы уже видите, что происходит? В вашей реализации метода переменная self устанавливается на первый аргумент objc_msgSend. Когда вы переназначаете self, ваш не редактирует какую переменную myInst содержит и, следовательно, вы не редактирование оригинала, который вы передали. Вы просто устанавливаете myInst, aka self, локальную переменную, на ваш знакомый указатель. Вызывающий функция не заметит изменения.

Сравните вы код на следующий код C:

void myFunction(int a) { 
    a = 3; 
} 

int b = 2; 
myFunction(b); 
printf("%d\n", b); 
// The variable b still has the original value assigned to it 

Приведенный выше код делает то же самое вы делаете:

// Variation on objc_msgSend 
void myMethodWrittenInC(id myInst) { 
    // Local variable changes, but will not change in the calling code 
    myInst = nil; 
} 

MyClass *myObj; 

myObj = [[MyClass alloc] init]; 
myMethodWrittinInC(myObj); 
// At this point myObj is not nil 

И, наконец, это то, что вы делаете:

- (void)testMethod 
{ 

    NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"myEncodedObjectKey"]; 
    // You assign the local variable self (passed as an invisible argument 
    // to your method) to your new instance, but you do not edit the original 
    // instance self pointed to. The variable currentProfile does not change. 
    self = (Profile *) [NSKeyedUnarchiver unarchiveObjectWithData:data]; 

    for (int i = 0; i < self.avatar.count; i++) 
     [self.avatar 
     replaceObjectAtIndex:i 
     withObject:[UIImage imageWithData:[self.avatar objectAtIndex:i]]]; 

    if ([[self.avatar objectAtIndex:0] isKindOfClass:[UIImage class]]) 
     NSLog(@"UIImage");//at this moment it's UIImage 
} 


// (1) Here currentProfile points to an instance of your class 
[currentProfile testMethod]; 
// (2) it calls the method, but the local variable does not change 
// and still points to the same instance. 

if ([[currentProfile.avatar objectAtIndex:0] isKindOfClass:[NSData class]]) 
    NSLog(@"NSData");//Moment later it is NSData 
+0

Ты гениальный! Большое спасибо, приятель! –

+0

Это то, что написано в вашем профиле: «Если у вас есть какие-либо вопросы относительно программирования или запроса, не стесняйтесь обращаться ко мне». У меня всегда есть много вопросов о кодировании, как настоящий, поэтому, если вы не шутите, я немного побеспокою вас. –

+0

Нет проблем. Я всегда в настроении помочь – v1Axvw

Смежные вопросы