json-framework: EXC_BAD_ACCESS on stringWithObject - objective-c

UPDATE:
I found that the reason for the previous error was an error in the documentation.
The method should be named proxyForJson, not jsonProxyObject...
But I'm still stuck, though.
I now get an EXC_BAD_ACCESS error inside stringWithObject some where. Any clues?
UPDATE 2:
My proxyForJson implementation is a cut-n-paste from then documentation:
- (id)proxyForJson {
return [NSDictionary dictionaryWithObjectsAndKeys:
Navn, #"Navn",
Adresse, #"Adresse",
Alder, #"Alder",
nil];
}
Trying to make json serialization work for my custom objective-c class.
As I understand the documentation, json-framework can serialize custom objects, if they implement the jsonProxyObject method.
So I have this class:
#interface MyObject : NSObject {
NSString *Name;
NSString *Addresse;
NSInteger Age;
}
#property (nonatomic, retain) NSString *Name;
#property (nonatomic, retain) NSString *Addresse;
#property (nonatomic, assign) NSInteger Age;
- (id)jsonProxyObject;
#end
And I try to serialize an array with some instances in it:
[json stringWithObject:list error:&error];
But all I get is he following error:
"JSON serialisation not supported for MyObject"
I guess the jsonWriter can't find my jsonProxyObject method for some reason, buy why?
Regards.

Have you tried to turn on NSZombies and MallocStackLogging in your Executable Info pane to check the source of the EXC_BAD_ACCESS? If not, you might try this and check the console for the output.
EXC_BAD_ACCESS is often an error caused by over-releasing an object somewhere.

I am not sure whether this is the right thing to do but defining the class as follows, solves the problem:
#interface MyObject : NSObject {
NSString *Name;
NSString *Addresse;
NSInteger *Age;
}
#property (nonatomic, retain) NSString *Name;
#property (nonatomic, retain) NSString *Addresse;
#property (nonatomic, retain) NSInteger *Age;
- (id)jsonProxyObject;
#end
Then initializing the variable as:
Age = [[NSNumber alloc] initWithInt:32];

In NSString, there is no stringWithObject: method. You should try using stringWithFormat: instead.

Related

NSObject returns nothing XCode 6

I moved my app to XCode 6 and found this problem. I have NSObject and it stopped returning objects when initialized, I use XCode 6 iPhone 6 Simulator.
My .h file:
#import <Foundation/Foundation.h>
#interface RBGAlpha : NSObject{
NSString *red;
NSString *blue;
NSString *green;
NSString *alpha;
}
#property (nonatomic, retain) NSString *red;
#property (nonatomic, retain) NSString *blue;
#property (nonatomic, retain) NSString *green;
#property (nonatomic, retain) NSString *alpha;
-(id)initWithName:(NSString *)r bl:(NSString *)b gr:(NSString *)g al:(NSString *)a;
#end
my .m file
#import "RBGAlpha.h"
#implementation RBGAlpha
#synthesize red,blue,green,alpha;
-(id)initWithName:(NSString *)r bl:(NSString *)b gr:(NSString *)g al:(NSString *)a{
self = [super init];
if (self) {
self.red = r;
self.blue = b;
self.green = g;
self.alpha = a;
}
return self;
}
#end
I use something like this in viewDidLoad method to create my objects:
RBGAlpha *tmpObj=[[RBGAlpha alloc] initWithName:#"0.01" bl:#"0.01" gr:#"0.01" al:#"1.00"];
However, while running the app in Simulator iPhone 6 this returns nothing
Has anybody dealt with that kind of problem?
I think that you're being mislead. There is indeed a value, that is what 0x786... in the value field means.
Summary saying 0 objects is confusing. I cannot understand why it would say that, but I bet if you typed po tmpObj into LLDB it would not return nil but the address showing next to "Value".
If you want to see something more interesting from the Xcode debugger consider implementing debugQuickLookObject.
On a side note, you can omit the definition of your instances variables in
#interface RBGAlpha : NSObject{
NSString *red;
NSString *blue;
NSString *green;
NSString *alpha;
}
And you also don't need to #synthesize each of them anymore, the compiler included with Xcode 5 and up does this for you.

How can I cast my NSURLSessionDownloadTask to my custom NSURLSessionDownloadTask (inheritance)?

I have created a custom NSURLSessionDownloadTask named VJSessionTask and I have just added some custom things like a type (enum) and a custom object (id):
#interface VJSessionTask : NSURLSessionDownloadTask
typedef enum types
{
LS, LSH, DL, UL, RM, TH
} type;
#property enum types type;
#property (strong, nonatomic) id customObject;
#property (strong, nonatomic) NSString *progressNotif;
#property (strong, nonatomic) NSString *doneNotif;
#property (strong, nonatomic) NSURL *tmpFile;
#end
And when I do this:
VJSessionTask *taskSession = (VJSessionTask *)[self.prioritySession downloadTaskWithRequest:listFileRequest];
// init taskSession with its type
taskSession.type = LS;
I get this error:
-[__NSCFLocalDownloadTask setType:]: unrecognized selector sent to instance 0x1556198f0
Then I come to you as I don't understand or I don't know how to do that...
Thank you in advance ;)
NSURLSessionTasks are not strictly speaking subclass-able unfortunately. This is evident in that the system can queue a data task and return a NSCFLocalDownloadTask (presumably meaning that the task will return its content from the cache).
The best way to go about doing this is to borrow on from the architectural decision of AFNetworking and have individual taskDelegates that monitor all the responses an individual task works on. Then when you want to find the data relating to a task you can query your dictionary of taskDelegates. Each task has a unique identifier that you can use to key your dictionary with.
In AFNetworking you can see the taskDelegate is defined as follows:
#interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
#property (nonatomic, weak) AFURLSessionManager *manager;
#property (nonatomic, strong) NSMutableData *mutableData;
#property (nonatomic, strong) NSProgress *progress;
#property (nonatomic, copy) NSURL *downloadFileURL;
#property (nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading;
#property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler;
#end
#implementation AFURLSessionManagerTaskDelegate
and subsequently retrieved as follows:
- (AFURLSessionManagerTaskDelegate *)delegateForTask:(NSURLSessionTask *)task {
NSParameterAssert(task);
AFURLSessionManagerTaskDelegate *delegate = nil;
[self.lock lock];
delegate = self.mutableTaskDelegatesKeyedByTaskIdentifier[#(task.taskIdentifier)];
[self.lock unlock];
return delegate;
}
See this post for more info

I want to declare a property for CFStringRef, how can I do?

Generally, we delare property like this:
#Property (nonatomic, retain) NSString * string;
#property (nonatomic, assign) NSInteger number;
But if I want to declare a CF object, how can I do?
Is it the same under ARC?
#property(nonatomic, strong) __attribute__((NSObject)) CFStringRef myString;
This way, ARC will do all the work for you.
Because there is tollfree bridging between NSString and CFStringRef, you could also do:
#property (nonatomic, strong) NSString *myString;
and when setting the property with a CFStringRef:
CFStringRef myStringRef = CFSTR("Hello!");
myObject.myString = (__bridge_transfer NSString *)myStringRef;
See also: http://amattn.com/2011/12/07/arc_best_practices.html
and: assign properties, ARC and Core Foundation objects

Trouble with shadowing #property in objective-c

Why isn't a setter synthesized for myString in the example below? The basic assignment below results in myString being nil. Trying to use the setter [self setMyString:s]; results in an unrecognized selector exception.
// in .h file
#interface MyClass
#property (nonatomic, readonly) NSString *myString;
#end
// in .m file
#interface MyClass (MyCategory)
#property (nonatomic, copy) NSString *myString;
#end
#implementation MyClass
#synthensize myString;
- (void) someMethod:(NSString *) s {
myString = [s copy];
// why is myString nil here?
}
#end
Edit: the problem was with gdb. po myString printed Can't print description of a NIL object.. However NSLog(#"myString: %#", myString); printed the expected value.
The other two answers are correct, but I think they miss your intention. It's common to declare a property as read-only in the .h file, so that code outside the class implementation can't write it. Inside the .m file, you want it to be readwrite. This kind of redefinition is explicitly supported. However, you need to put the redeclaration as readwrite in a class-extension:
// In your .h file:
#interface MyClass : NSObject
#property (nonatomic, copy, readonly) NSString *myString;
#end
// In your .m file:
#interface MyClass () // Note the empty parentheses
#property (nonatomic, copy, readwrite) NSString *myString;
#end
You do still need to use self.myString = aString or [self setMyString:aString], instead of writing to the ivar directly as you're doing right now.
It looks like you're trying to declare a publicly readonly, privately writable property. You should do that in a class extension rather than a category. Syntactically, a class extension looks like a category with no name:
#interface MyClass ()
#property (nonatomic, copy) NSString *myString;
#end
Declaring a property with the same name in both your MyClass interface and your MyCategory category seems like a bad idea. Remove the declaration in the category and I expect all will be well.

Properties declared as instance variables too?

This code works:
#interface StringStuff : NSObject {
}
#property (nonatomic, retain) NSString *String1;
#property (nonatomic, retain) NSString *String2;
- (NSString *) doSomethingWithStrings;
#end
But I often see:
#interface StringStuff : NSObject {
NSString *String1;
NSSTring *String2;
}
#property (nonatomic, retain) NSString *String1;
#property (nonatomic, retain) NSString *String2;
- (NSString *) doSomethingWithStrings;
#end
Is there a reason that properties are often declared as an instance variable as well? Is it just considered good form?
Legacy; it used to be (and still is on 32 bit Mac OS X targeted code) that the ivar declarations were required. That is no longer true on iOS, the simulator and 64 bit OS X.
Note that it is common to #synthesize iVar = iVar_; to prevent accidental direct access where self.iVar is really required.