2015년 5월 11일 월요일

objc_setAssociatedObject , objc_getAssociatedObject


#import <objc/runtime.h>


예제1)

// set
    {
        objc_setAssociatedObject(self, @"ShouldDismissModalViewLater", modalViewController, OBJC_ASSOCIATION_ASSIGN);
    }
    
    // get and using
    {
        UIViewController *modalVC = objc_getAssociatedObject(self, @"ShouldDismissModalViewLater");
        [modalVC dismissViewControllerAnimated:YES completion:nil];
    }



예제2)

// set
    {
        NSArray *gotArray;
        objc_setAssociatedObject(self, @"MyGotArray", gotArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    // get and using
    {
        NSArray *array = objc_getAssociatedObject(self, @"MyGotArray");
        [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            
        }];
    }


예제3)
Easier syntax
Alternatively you could use @selector(nameOfGetter) instead of creating a static pointer. Why? See http://stackoverflow.com/a/16020927/202451. Example:
- (NSArray *)laserUnicorns {
    return objc_getAssociatedObject(self, @selector(laserUnicorns));
}

- (void)setLaserUnicorns:(NSArray *)unicorns {
    objc_setAssociatedObject(self, @selector(laserUnicorns), unicorns, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
}

async download images

NSURLSession를 이용한 방법)

xxx.h
NSURLSession *mealNewsUrlSession;

xxx.m

// initialization
mealNewsUrlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];


// use
NSURL *imageURL = [NSURL URLWithString:imagePath];
            NSURLRequest *request = [NSURLRequest requestWithURL:imageURL];
            NSURLSessionDataTask *task = [mealNewsUrlSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                if (error)
                {
                    NSLog(@"ERROR: %@", error);
                }
                else
                {
                    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                    
                    if (httpResponse.statusCode == 200)
                    {
                        UIImage *image = [UIImage imageWithData:data];
                        [mealNewsImageCache setObject:image forKey:imagePath];
                        
                        dispatch_async(dispatch_get_main_queue(), ^{
                            [cell.mealPhoto setImage:image];
                            [cell setNeedsLayout];
                            //[cell.activityIndicator stopAnimating];
                        });
                    }
                    else
                    {
                        NSLog(@"Couldn't load image at URL: %@", imageURL);
                        NSLog(@"HTTP %ld", (long)httpResponse.statusCode);
                    }
                }
            }];

            [task resume];


dispatch를 이용한 방법)

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
        dispatch_async(queue, ^(void) {
            
            NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:profilePath]];
            UIImage* image = [[UIImage alloc] initWithData:imageData];
            if (image) {
                [mealNewsImageCache setObject:image forKey:profilePath];
                
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self.profilePhoto setImage:image forState:UIControlStateNormal];
                });
            }

        });

3. 한번에 모두 다운로드 한후에 이용하는 방법)

xxx.h
NSOperationQueue *_asyncQueue;

xxx.m
// initialization
{
_asyncQueue = [[NSOperationQueue alloc] init];
or
_asyncQueue = [NSOperationQueue mainQueue]
or
_asyncQueue = [NSOperationQueue currentQueue]
}

{
// use
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [NSURLConnection sendAsynchronousRequest:request queue:_asyncQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            
            UIImage *image = [[UIImage alloc] initWithData:data];
            [Utility saveImageToFS:UIImageJPEGRepresentation(image, 1.0) withUrl:request.URL];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                //update cell
            });
        }];
    }); //dispatch_async
}

+ (void) saveImageToFS:(NSData *)data withUrl:(NSURL *)url {
    NSString *dir = [[url absoluteString] stringByDeletingLastPathComponent];
    NSString *filename = [url.absoluteString lastPathComponent];
    
    //
    NSString *path = [NSString stringWithFormat:@"%@/%@",[Utility getMangaRootPath],dir];
    if(![[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil])
        NSLog(@"fail to create directory ");
    
    
    NSString *fullpath = [path stringByAppendingFormat:@"/%@",filename];
    if(![data writeToFile:fullpath atomically:YES])
        NSLog(@"fail to write file");
}

+ (NSString *)getMangaRootPath {
    NSString *path = [NSString stringWithFormat:@"%@/%@",
                      [self getCachesPath],
                      kMangaEditionDirectory];
    // create directory
    [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
    return path;
}

+ (NSString*)getCachesPath {
    NSString *documentPath = nil;
    
    NSSearchPathDirectory directory;
    directory = NSCachesDirectory;
    
    NSArray* directories = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES);
if(directories != nil && [directories count] > 0)
        documentPath = [directories objectAtIndex:0];
    return documentPath;
}