+ (NSDictionary *)mc_inboundMapping {
static NSMutableDictionary *mappingForClassName = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mappingForClassName = [NSMutableDictionary dictionary];
});
#synchronized(mappingForClassName) {
NSDictionary *mapping = mappingForClassName[[self className]];//<----EXC BAD ACCESS here
if (!mapping) {
SEL selector = NSSelectorFromString(#"JSONInboundMappingDictionary");
if ([self respondsToSelector:selector]) {
mapping = MCValueFromInvocation(self, selector);
}
else {
mapping = [self mc_defaultInboundMapping];
}
mappingForClassName[[self className]] = mapping;
}
return mapping;
}
I'm using Realm+JSON with Realm. And got a problem with Realm+JSON.
When I attempt to call createOrUpdateInRealm:withJSONArray: multiple time in loop for multiple RLMObjects, the first RLMObject works OK, but the second RLMObject(no matter what class is) fails with EXC BAD ACCESS code1on static variable.
I think autorelease pool deallocate pointing NSMutableDictionary.Anybody got this issue? I'm using XCode 6.3.2 and Realm 0.96.3.
+ (NSArray *)createOrUpdateInRealm:(RLMRealm *)realm withJSONArray:(NSArray *)array {
NSInteger count = array.count;
NSMutableArray *result = [NSMutableArray array];
for (NSInteger index=0; index*kCreateBatchSize<count; index++) {
NSInteger size = MIN(kCreateBatchSize, count-index*kCreateBatchSize);
#autoreleasepool
{
for (NSInteger subIndex=0; subIndex<size; subIndex++) {
NSDictionary *dictionary = array[index*kCreateBatchSize+subIndex];
id object = [self createOrUpdateInRealm:realm withJSONDictionary:dictionary];
[result addObject:object];
}
}
}
return [result copy];
}
calling here...
[realm beginWriteTransaction];
if ([collection isKindOfClass:[NSDictionary class]])
{
for (NSString *key in [collection allKeys])
{
NSLog(#"Set Data == %#:%#", key, collection[key]);
id jsData = [collection[key] objectForKey:#"data"];
if ([key isEqualToString:STATIC_ERROR_MSGS])
{
[SErrorMsgs createOrUpdateInRealm:realm withJSONArray:jsData];
}
else if ([key isEqualToString:STATIC_EPISODE])
{
[SEpisode createOrUpdateInRealm:realm withJSONArray:jsData];
}
else if ([key isEqualToString:STATIC_INGAME_TUTORIAL])
{
[SIngameTutorial createOrUpdateInRealm:realm withJSONArray:jsData];
} //more cases.........edited
Related
I have 100 key and value in nsmutabledictornary and i want to check that any value have null or not. Do you have any short function or technique?
I don't want to multiple line code like check every key and value. Your answer would be appreciated.
This code will give you the set of keys which have (non)null values. You can't store actual nil values in a dictionary, so [NSNull null] is assumed. The predicate is trivially alterable to any other condition.
NSDictionary *d = #{ #"a" : #"1", #"b" : [NSNull null] };
NSSet *nullKeys = [d keysOfEntriesPassingTest:^BOOL(NSString *key, id obj, BOOL *stop) {
return [d[key] isKindOfClass:[NSNull class]];
}];
NSSet *nonnullKeys = [d keysOfEntriesPassingTest:^BOOL(NSString *key, id obj, BOOL *stop) {
return [d[key] isKindOfClass:[NSNull class]] == NO;
}];
From here, you can use the keys to generate a corresponding dictionary, if needed.
NSMutableDictionary *nonNullDict = [NSMutableDictionary dictionary];
[d enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
if ([nonnullKeys contains:key]) {
nonNullDict[key] = obj;
}
}];
If you don't need a separate list of keys, and just need the filtered dictionary, skip the first step and modify the second part to read as follows:
NSMutableDictionary *nonNullDict = [NSMutableDictionary dictionary];
[d enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
if ([obj isKindOfClass:[NSNull null]] == NO) {
nonNullDict[key] = obj;
}
}];
Write category on NSDictionary it will provide you null free dictionary. Here is the category I have written for myself.
code for .h file (interface)
#import <Foundation/Foundation.h>
#interface NSDictionary (CheckNull)
{
}
- (NSDictionary *)nullFreeDictionary;
#end
Code for .m file. (implementation)
#import "NSDictionary+CheckNull.h"
#implementation NSDictionary (CheckNull)
- (NSDictionary *) nullFreeDictionary
{
NSMutableDictionary *tempDictionary = [self mutableCopy];
for (NSString *key in tempDictionary.allKeys) {
NSString *value = [tempDictionary valueForKey:key];
if ([value isKindOfClass:[NSString class]]) {
if (value == (id)[NSNull null] || value == nil || value.length == 0) {
[tempDictionary setValue:#"" forKey:key];
}
}
}
return tempDictionary;
}
Call null free method on your dictionary using above category.
NSDictionary *dict = [dict nullFreeDictionary];
//To remove NULL from Dictionary
-(NSMutableDictionary *)removeNullFromDictionary : (NSMutableDictionary *)dict
{
// if (![dict isKindOfClass:[NSMutableDictionary class]])
// {
// }
dict = [[NSMutableDictionary alloc] initWithDictionary:dict];
for (NSString * key in [dict allKeys])
{
if ([dict[key] isKindOfClass:[NSNull class]])
{
[dict setValue:#"" forKey:key];
}
else if ([dict[key] isKindOfClass:[NSMutableDictionary class]]||[dict[key] isKindOfClass:[NSDictionary class]])
{
dict[key] = [self removeNullFromDictionary:[NSMutableDictionary dictionaryWithDictionary:dict[key]]];
}
else if ([dict[key] isKindOfClass:[NSMutableArray class]]||[dict[key] isKindOfClass:[NSArray class]])
{
dict[key] = [self removeNullFromArray:[NSMutableArray arrayWithArray:dict[key]]];
}
}
return dict;
}
//To remove NULL from Array
-(NSMutableArray *)removeNullFromArray : (NSMutableArray *)arr
{
// if (![arr respondsToSelector:#selector(addObject:)])
// {
// arr = [[NSMutableArray alloc] initWithArray:arr];
// }
arr = [[NSMutableArray alloc] initWithArray:arr];
for (int cnt = 0; cnt<[arr count]; cnt++)
{
if ([arr[cnt] isKindOfClass:[NSNull class]])
{
arr[cnt] = #"";
}
else if ([arr[cnt] isKindOfClass:[NSMutableDictionary class]]||[arr[cnt] isKindOfClass:[NSDictionary class]])
{
arr[cnt] = [self removeNullFromDictionary:[NSMutableDictionary dictionaryWithDictionary:arr[cnt]]];
}
else if ([arr[cnt] isKindOfClass:[NSMutableArray class]]||[arr[cnt] isKindOfClass:[NSArray class]])
{
arr[cnt] = [self removeNullFromArray:[NSMutableArray arrayWithArray:arr[cnt]]];
}
}
return arr;
}
I have two methods to save and load NSManagedObject (updated to original):
-(void) saveToCoreData: (TeamManagedObject *)teamSet{
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelDebug);
if(!teamSet) {
self.teamSet = [NSEntityDescription insertNewObjectForEntityForName:#"TeamManagedObject" inManagedObjectContext:self.managedObjectContext];
} else {
self.teamSet = teamSet;
}
[self.teamSettings enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[self.teamSet setValue:obj forKey:key];
}];
NSError *saveError = nil;
[self.managedObjectContext save:&saveError];
}
-(id)load:(TeamManagedObject *)managedObject {
unsigned int count = 0;
objc_property_t *properties = class_copyPropertyList([TeamManagedObject class], &count);
for (int i = 0; i < count; i++) {
NSString *key = [NSString stringWithUTF8String:property_getName(properties[i])];
NSString *value = [managedObject valueForKey:key];
if (value) {
[self setObject:value forKey:key];
}
}
self.teamSet = managedObject;
free(properties);
return self;
}
1) call method [self save:nil] - object creates and saves to CoreData correctly. (value is correct after having app restarted)
2) restarting app and calling load method - it was loaded correctly
3) calling save [self save:object] method with loaded object - it looks like saved, but only before app was restarted... after app restarting, object have an old value...
Where is the mistake?
Thanks!
-(void) objectParsed_ListAllMedia:(NSDictionary *)dictionary
{
#try {
self.viewLoading.hidden=1;
[self.arrGaalleryMediaName removeAllObjects];
[self.arrMediaNames removeAllObjects];
if(self.arrOnlyServerImages == nil){
self.arrOnlyServerImages = [[NSMutableArray alloc] init];
}
if([self.arrOnlyServerImages count] >0){
[self.arrOnlyServerImages removeAllObjects];
}
if (dictionary==nil) {
[self.gridCollectionView reloadData];
return;
}
// Filter Array for Audio file
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"type != 'audio' "];
self.arrOnlyServerImages = [NSMutableArray arrayWithArray:[[dictionary objectForKey:#"objects"] filteredArrayUsingPredicate:predicate]];
// Remove duplicate Start //Read Meta Data and Duplicate from Download, Duplicate from upload START
dispatch_queue_t backgroundQueue = dispatch_queue_create("com.memreas.myqueue", 0);
dispatch_async(backgroundQueue, ^{
NSMutableArray *arr = [NSMutableArray array];
NSMutableIndexSet * indexSet = [NSMutableIndexSet indexSet];
for (int i=0; self.assetAry.count>i; i++) {
ALAsset *result =self.assetAry[i];
ALAssetRepresentation *imageRep = [result defaultRepresentation];
NSDictionary * customMetaDic = [imageRep metadata][(NSString*)kCGImagePropertyIPTCDictionary];
if (customMetaDic) {
[self.arrMediaNames addObject:customMetaDic[(NSString*)kCGImagePropertyIPTCObjectName]?customMetaDic[(NSString*)kCGImagePropertyIPTCObjectName]:#""];
}else{
[self.arrMediaNames addObject:#""];
}
[self.arrGaalleryMediaName addObject:[self getFileNameWithExtensionFromPath:imageRep.url]];
}
for (int i=0; self.arrOnlyServerImages.count>i; i++) {
NSMutableDictionary* obj = self.arrOnlyServerImages[i];
NSMutableDictionary * dic2 = [NSMutableDictionary dictionaryWithDictionary:obj];
BOOL isArrMedia =[self.arrMediaNames containsObject:dic2[#"media_name"]];
BOOL isGallery =[self.arrGaalleryMediaName containsObject:dic2[#"media_name"]];
if (isArrMedia||isGallery) {
dic2[#"isDownloaded"] = [NSNumber numberWithBool:YES];
[indexSet addIndex: isArrMedia?[self.arrMediaNames indexOfObject:dic2[#"media_name"]] :[self.arrGaalleryMediaName indexOfObject:dic2[#"media_name"]]];
}else{
dic2[#"isDownloaded"] = [NSNumber numberWithBool:NO];
}
[arr addObject:dic2];
}
dispatch_async(dispatch_get_main_queue(), ^{
#try {
self.arrOnlyServerImages = arr;
[self.assetAry removeObjectsAtIndexes:indexSet];
[self.gridCollectionView reloadData];
}
#catch (NSException *exception) {
NSLog(#"%#",exception);
[self.gridCollectionView reloadData];
}
});
});
// Remove duplicate END //Read Meta Data and Duplicate from Download, Duplicate from upload END
[self.gridCollectionView reloadData];
[self.gridView.collectionView reloadData];
[self.location performSelector:#selector(stopActivity) withObject:nil afterDelay:2];
}
#catch (NSException *exception) {
NSLog(#"%#",exception);
}
}
I have issue with my code, While I run this code it generates memory pressure issue and crash the app.
Functionality is:
I load all the images from server and local assets and match each other with file name and remove duplicate images from list, So it will visible only once.
Any one have solution so please help.
thanks in advance.
You're accessing memory-intensive things (ALAssetRepresentations) in a tight loop. In these cases a local autoreleasepool can help ARC to keep your memory use down.
Inside the loop where you pass through self.assetAry, wrap everything in an autoreleasepool like so:
#autoreleasepool {
AlAsset *asset = ...
...
// Rest of your code
}
The following code is in my implementation file:
NSMutableArray *courseArray;
- (IBAction)btnClick:(id)sender
{
NSDictionary *courseNames;
if(![_txtBox.text isEqual:#""]) //if not empty
{
courseNames = [self retrieveCourseNamesForSemester:_txtBox.text];
for (NSString *key in courseNames)
{
NSString *val = [NSString stringWithFormat:#"%#-%#",key,[courseNames objectForKey:key]];
_txtView.text = val;
#try
{
[courseArray addObject:val];
}
#catch(NSException *e)
{
NSLog(#"Exception: %# for value = %#", e, val);
}
}
}
[_coursePicker reloadAllComponents];
_coursePicker.hidden=false;
[_txtBox resignFirstResponder];
}
Where you see the call to NSLog(), I get the following error message:
2014-03-29 00:02:25.830 WebServiceTest[44646:60b] Exception: -[__NSArrayI addObject:]: unrecognized selector sent to instance 0x8d82c30 for value = 73-522-Course Name
EDIT: Also, courseArray is populated with sample data in viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
courseArray = #[#"Australia (AUD)", #"China (CNY)",
#"France (EUR)", #"Great Britain (GBP)", #"Japan (JPY)"];
}
Is there somewhere I should be defining that courseArray will take NSString objects?
The code in viewDidLoad creates an immutable array. You need to make a mutable copy, like this
(void)viewDidLoad
{
[super viewDidLoad];
courseArray = [#[#"(AUD)", #"(CNY)", #"(EUR)"] mutableCopy];
}
Try this code,
for (NSString *key in courseNames)
{
NSString *val = [NSString stringWithFormat:#"%#-%#",key,[courseNames objectForKey:key]];
_txtView.text = val;
if ([CourseArray count]==0)
{
CourseArray= [NSMutableArray arrayWithObject:val];
}
else
{
[CourseArray addObject:val];
}
}
I have an array of custom objects. The objects represent segments in a binary file.
The property loc holds the objects own location in the file, where prev holds the location of the "previous" object. In this context "previous" and "next" doesn't necessarily mean that the objects occur after each other in the file.
The first object has prev = 0. The last object has no following object holding its location as prev.
How do I achieve such kind of sorting? Number of objects is initially not known.
//My custom object
#interface MyObject : NSObject
#property (nonatomic, assign) NSInteger loc, prev;
#end
//In the implementation of some other class
NSMutableArray *array = [NSMutableArray new];
{// order should be 6
MyObject *obj = [MyObject new];
obj.loc = 3000;
obj.prev = 111;
[array addObject:obj];
}
{// order should be 2
MyObject *obj = [MyObject new];
obj.loc = 2000;
obj.prev = 222;
[array addObject:obj];
}
{// order should be 4
MyObject *obj = [MyObject new];
obj.loc = 333;
obj.prev = 4000;
[array addObject:obj];
}
{// order should be 1
MyObject *obj = [MyObject new];
obj.loc = 222;
obj.prev = 5000;
[array addObject:obj];
}
{// order should be 5
MyObject *obj = [MyObject new];
obj.loc = 111;
obj.prev = 333;
[array addObject:obj];
}
{// order should be 3
MyObject *obj = [MyObject new];
obj.loc = 4000;
obj.prev = 2000;
[array addObject:obj];
}
{// order should be 0
MyObject *obj = [MyObject new];
obj.loc = 5000;
obj.prev = 0;
[array addObject:obj];
}
Try using lexicographical sorting:
NSArray *sorted = [array sortedArayUsingComparator:^(id obj1, id obj2) {
if ([obj1 parentID] < [obj2 parentID] {
return NSOrderedAscending;
} else if ([obj1 parentID] > [obj2 parentID] {
return NSOrderedDescending;
} else if ([obj1 ID] < [obj2 ID] {
return NSOrderedAscending;
} else if ([obj1 ID] > [obj2 ID] {
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}];
Never mind, I got it.
NSMutableArray *unordered = [[NSMutableArray alloc] initWithArray:array];
NSMutableArray *ordered = [NSMutableArray new];
for(MyObject *myObj in array)
{
if(!myObj.prev)
{
[orderedTables addObject:myObj];
[unorderedTables removeObject:myObj];
break;
}
}
int counter = 0;
while(unordered.count && counter < ordered.count)
{
MyObject *obj1 = [ordered objectAtIndex:counter++];
for(int i = 0; i < unordered.count; ++i)
{
MyObj *obj2 = [unordered objectAtIndex:i];
if(obj2.prev == obj1.loc)
{
[ordered addObject:obj2];
[unordered removeObject:obj2];
break;
}
}
}