2012-01-12 6 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 
} 

이 : 내가 NSUserDefaults에서 사용자 지정 개체를 가져오고 "아바타"라는 이름의 NSMutableArray를 변수로 작동 처음에

[currentProfile testMethod]; 

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

. 각 개체를 NSData에서 UIImage로 변환합니다. 그런 다음 NSLog를 사용하여 얻은 내용을 확인합니다. UIImage입니다. 두 번째 코드에서는 UMLmage가 나중에 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 (별칭 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

관련 문제