我有一个User
类的模型。用户具有picture
NSImage
属性(在coredata中设置可转换)。我想要做的是在第一次访问时从服务器检索图片。
第一个解决方案(可行,但我不喜欢)是添加一个类别和另一个NSImage属性。 UI与第二个属性有关。第一次访问它时,它连接到服务器并检索图像。
这个解决方案的问题是我必须向我的appdelegate中创建和初始化的httpclient(我使用AFNetworking,所以AFHTTPClient
)的引用传递给这个类。目前它是一个单身人士,但我不喜欢这个解决方案。
所以......这是我正在尝试的第二件事:
我在AFHTTPClient
包装器类
- (void)loadPictureForUser:(User*)user
imageLoadedCallback:(void(^)())callback
{
//if picture is already loaded do nothing
if (user.picture) return;
//if the request is already "ongoing" then do nothing
if ([self.imageLoadingRequests objectForKey:user.id]) return;
//We have to make a request
//set the placeholder while we wait for the image
#if TARGET_OS_IPHONE
user.picture = [UIImage imageNamed:@"UnknownUserPicture"];
#else
user.picture = [NSImage imageNamed:@"UnknownUserPicture"];
#endif
//make the request
NSDictionary *params = @{
@"id" : user.id,
@"size" : @(80),
@"count" : @(random() % 1000000)};
AFHTTPClient *httpClient = self.httpClient;
NSURLRequest *imageRequest = [httpClient requestWithMethod:@"GET"
path:ServerGetUserPictureURL
parameters:params];
__weak ConnectionManager *weakSelf = self;
AFImageRequestOperation *imageRequestOperation =
#if TARGET_OS_IPHONE
[AFImageRequestOperation imageRequestOperationWithRequest:imageRequest
imageProcessingBlock:nil
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
user.picture = image;
//in every case I have to remove the entry from the dictionary
[weakSelf.imageLoadingRequests removeObjectForKey:user.id];
BLOCK_SAFE_EXEC(callback);
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
//in every case I have to remove the entry from the dictionary
[weakSelf.imageLoadingRequests removeObjectForKey:user.id];
}];
#else
[AFImageRequestOperation imageRequestOperationWithRequest:imageRequest
imageProcessingBlock:nil
success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSImage *image) {
//save the picture in the user
user.picture = image;
user.picture.name = user.nickname;
//in every case I have to remove the entry from the dictionary
[weakSelf.imageLoadingRequests removeObjectForKey:user.id];
BLOCK_SAFE_EXEC(callback);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
//in every case I have to remove the entry from the dictionary
[weakSelf.imageLoadingRequests removeObjectForKey:user.id];
}];
#endif
[self.imageLoadingRequests setObject:imageRequestOperation forKey:user.id];
[httpClient enqueueHTTPRequestOperation:imageRequestOperation];
}
此方法设置占位符,直到它检索到正确的图片。
从自定义NSValueTransformer
- (id)transformedValue:(id)value
{
if (![value isKindOfClass:[User class]])
return nil;
User *user = value;
[self.connectionManager loadPictureForUser:value imageLoadedCallback:NULL];
return user.picture;
}
占位符设置正确(显然)。 问题是,当设置正确的图片时,UI不会更新。 我认为这可能是我如何绑定属性的问题......
我在两个不同的地方使用它:
NSImageView
..我将value
属性直接绑定到fileowner.connectionManger.user(fileowner是一个NSWindowController
子类,连接管理器跟踪用户是登录)然后我在上面设置变压器。NSTableView
。 NSArrayController
绑定到包含类NSArray
的{{1}}对象。每个都有一个属性News
,它是一个creator
对象。所以表中行内的imageview绑定到User
,然后绑定到同一个变换器。关于为什么这不起作用的一些想法?
编辑:我删除了关于''以编程方式''作品的陈述。 我看到它工作但也许是出于其他原因。 所以...当我设置objectValue.creator
值时,没有KVO通知发送到我的观察对象......
我开始认为我没有正确处理KVO协议,但我阅读了指南,但仍然无法弄清楚错误。
对于第一个''case''(user.picture
绑定),我绑定的用户对象位于包装器内。因此,如果我理解正确,包装器应该与用户对象的KVO兼容。但我认为是:
NSImageView
当然@property (nonatomic, strong, readonly) User *user;
对象是User
子类(但我的控制器与NSManagedObject
无关......但我不认为这是问题......