UIImage 神秘地转换为 NSData
Posted
技术标签:
【中文标题】UIImage 神秘地转换为 NSData【英文标题】:UIImage converts to NSData mysteriously 【发布时间】:2012-01-12 17:50:18 【问题描述】:请看一下这两个简单的代码。这个
- (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 中获取一个自定义对象,并使用一个名为“avatar”的 NSMutableArray 变量。我将其每个对象从 NSData 转换为 UIImage。然后我使用 NSLog 检查我得到了什么。它是 UIImage。在第二段代码中,您可以看到 UIImage 是如何按照自己的意愿返回到 NSData 的。好像我清楚地描述了我的问题。你明白发生了什么吗?我不。非常感谢您的关注
【问题讨论】:
【参考方案1】:为什么要更改 -testMethod
方法中的 self 对象?这是非常违法的。
您实际上正在做的是将作为参数传递给您的方法的局部变量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
【讨论】:
你真是个天才!非常感谢,伙计! 这是您个人资料中的内容:“如果您对编程有任何疑问或要求,请随时与我联系”。我总是有很多关于像现在这样的编码的问题,所以如果你不是在开玩笑,我会打扰你一点。 没问题。我总是乐于助人以上是关于UIImage 神秘地转换为 NSData的主要内容,如果未能解决你的问题,请参考以下文章
如何将 JSON Image-String(不是 url)转换为 UIImage 以供查看
将 UIImage 转换为 NSData 并在 Swift 中转换回 UIImage?
将UIImage转换为NSData并在Swift中转换回UIImage?