UIImage imageNamed size - objective-c

New to Objective-C, Cocoa, and compiled languages in general so forgive my ignorance:
UIImage *myImage = [UIImage imageNamed:#"1-filter.jpg"];
NSLog(#"myImage.size=%#", myImage.size);
Results in
Thread 1: Porgram received signal: "EXC_BAD_ACCESS".
Why? How do I get the size of a UIImage?

The size is a structure.
Use either size.width, size.height or NSStringFromCGSize(myImage.size) for NSLog output.

This is a subtle, annoying-for-beginners error. (I actually just ran into this last week.)
When you use the format string %# in an NSLog, the argument must be some kind of Objective-C object. (Behind the scenes, when you do NSLog(#"%#", foo), the system calls [foo description] to figure out what string to output. If the variable you pass to NSLog is not an Objective-C object, the system will try to send a message to something that isn’t an object and then throw this error.)
In this particular case, you’re going to be getting an integer, so replace %# with %d in your format string to make everything work okay.
Additionally, as Eugene mentioned, you want to be accessing a part of the size object. So try
NSLog(#"size.height=%d", myImage.size.height);
Edit: this should actually be %f instead of %d, and please read the comments on this answer.

Related

Objective-C - NSLog - "%#" Referencing Character

I'm working through a BNR iOS Programming text and I came across this piece of code:
NSLog(#"%#", [items objectAtIndex:i]);
I am unsure of what "%#" is used for. I've seen other formats for referencing integers or characters, but I've never seen this.
I even checked this reference here and it had nothing.
Thanks!
%# is for printing objective-c objects.
To be a bit more precise. Every object is able to override
-(NSString *)description
This method is called when you use %#. It depends on the object what info of the object it will return in the NSString.
According to Apple:
Objective-C object, printed as the string returned by descriptionWithLocale: if available, or description otherwise. Also works with CFTypeRef objects, returning the result of the CFCopyDescription function.
Reference:
String Format Specifiers
I am working through the same text - and coming from a Java background, the "%#" formatter seems equivalent to the "toString" method that Java would have.
It is used to display custom information about an object.
There is a good example in the response to this StackOverflow question about the "toString()" equivalent.

Strange BAD_ACCESS when printing NSInteger

this is my first time asking something here, so don't be too harsh on me please :-). I have a strange "bad access" issue. In a class of mine I have a NSInteger along with a few other members. I override the - (NSString *)description method to print the values of everything like so (omitted the unrelevant part):
- (NSString *)description {
return [NSString stringWithFormat:#"Duration:%d", duration];
}
and then I print that using NSLog(#"%#", myObject) which is giving me EXC_BAD_ACCESS without any log messages, regardless of the NSZombieEnabled.
I have double checked the order of all formatting specifiers and
parameters - it's correct.
I tried changing the format specifier to %i and %# and didn't get any result
When I init my object I don't initialize
duration. Later, I assign it through a property #property NSInteger
duration. So I tried initializing the duration to 0 in my init
method but to no avail.
If I box duration to a NSNumber prior to
printing, it works.
When I remove the duration and leave all the
other ivars it works again.
I'm stumped, what am I doing wrong here?
Can you help me?
Thanks a lot!
EDIT: To summarize, It seems this is caused by differences between 32 and 64 bit platforms, because it's fine when run on an iphone 4 and has issues only when run in the simulator. I tried 3 different approaches - using %d and %i with the NSInteger variable itself, using %qi and using %ld/ %lx and I also tried to cast to int and long with the various format specifiers. Every time I can run on the device, but get EXC_BAD_ACCESS in the simulator.
The only guess here: NSInteger could be 64 bit in your case and %i (as well as %d) expects 32-bit integer, you can try %qi or (what seems to be better) cast the value explicitly.
When you run the app in the debugger, where exactly is the signal raised? Xcode will show you the precise line and stack of the problem.
When you are sure the crash happens in the stringWithFormat: method it's probably a matter of format specifiers. Apple's String Programming Guide contains information on how to handle NSInteger in a safe and platform independent way.
Maybe you need to synthesyse your property?

where is the memory leak

I have a line of code:
CGFloat *components = CGColorGetComponents([color CGColor]);
and the analyzer is saying that there is a leak here.
I tried free(components) but the app crashes when I do that.
Is there really a leak here since I didnt allocate anything. I know that CGColorGetComponents returns an array of 3 CGFloat's but when I try to free them it crashes.
Any help is appreciated.
See SO #792119.
Declaring the variable does not create the array. In fact, neither does CGColorGetComponents. Whatever created the CGColor object created the array and stored it inside the object; CGColorGetComponents lets you have the pointer to that storage.
In short, do not free your pointer.
You could, however, set it to NULL.
Maybe you should pass color.CGColor as argument?
Have a look at this thread: What does CGColorGetComponents() return?

Why I'm getting memory leaks with xmlTextReaderConstValue?

I'm writing my own wrapper class for parsing XML data. Usually I use the Leak Performance Tool to detect suspicios behaviour through forgetting to release allocated memory.
At this time I figured out that the following code (the first line becomes marked by the tool) brings me an enormous memory leak (leaks more the bigger the XML data file becomes).
the following part is used to receive the text inside a Node.
NSString *currentTagValue = [NSString stringWithCString:(char *)xmlTextReaderConstValue(XMLReader) encoding:NSUTF8StringEncoding];
SEL selector = NSSelectorFromString([NSString stringWithFormat:#"set%#:", [currentTag capitalizedString]]);
[currentItem performSelector:selector withObject:currentTagValue];
If I add
[currentTagValue release]
the memory leaks are gone.
This seems strange to me, because I don't allocate memory for the NSString manually. That's why I thought it would be autoreleased.
The whole situation becomes stranger if I compare the upper code example with the part that is responsible for obtaining the node name.
NSString *currentTagName = [NSString stringWithCString:(char *)xmlTextReaderConstName(XMLReader) encoding:NSUTF8StringEncoding];
SEL selector = NSSelectorFromString([NSString stringWithFormat:#"set%#:", [currentTagName capitalizedString]]);
Here I dont't have to add a manual release, everything works fine and I'm getting no memory leak.
I'm not sure if my described problem is a side-effect of the xml...ConstValue function (the working part uses xml...ConstName) or if the reason is the performed selector afterwards.
Thanks for reading, I hope anyone can explain it to me.
Are you using libxml2? I haven't used libxml2 yet, but I googled quickly and found this:
http://xmlsoft.org/html/libxml-xmlreader.html
Function: xmlTextReaderConstValue
Returns: the string or NULL if not
available. The result will be
deallocated on the next Read()
operation.
Compare that with xmlTextReaderConstName
Function: xmlTextReaderConstName
Returns: the local name or NULL if not
available, the string is deallocated
with the reader.
It may be a leak in the lib, or a false alarm as the result seems to be on a delayed release (or something entirely different as I have no firsthand experience to say otherwise). Is the program crashing because of the leak or not? If it is not, maybe it's just a false alarm.
Hope it helps.

Frustrating problem with NSTextView

I want to print out the Text contents of a NSTextView using the NSLog function in Objective-C. The code I have so far is:
NSString *s=[updateSource textStorage];
NSLog(s);
All I get is the error:
[NSConcreteTextStorage getCharacters:range:]: selector not recognized [self = 0x43f4b0]
Use [updateSource string] instead. [updateSource textStorage] is not an NSString, but rather an NSTextStorage.
It's not the cause of your problem, but you should be using NSLog(#"%#",s); to log your string. The first argument of NSLog should always be a format string, and not the value you're trying to log.
(if you don't, your app will likely crash if the value contains percent characters)