I tried Build and Analyze tool of Xcode very first time today.
and found some thing in this function
Please check the image:
-(IBAction)completeSessionButAct:(id)sender{
NSDictionary *tempDic = [[NSDictionary alloc] initWithObjectsAndKeys:[self view],#"mainview",
congratulationScreen,#"screen",
congScreenLabel,#"cong_screen_label",
congScrStatusLabel,#"cong_scr_status_label",
[sender superview],#"last_screen",nil];
[functionality completeSession:tempDic];
}
this function start from line 64 and end at 71
Can Any one explain me the memory leakage in this function.
The text as displayed in the image seems pretty clear to me: You are creating an object that you own (new, alloc, copy, retain [NARC] does that); but you never rescind ownership.
Try using +[NSDictionary dictionaryWithObjectsAndKeys:] instead.
Related
It appears that XCtest "self measureBlock" is limited to milliseconds and 10 runs of the test code. Are there any ways to modify the behavior of measureBlock for more runs and/or nano or microsecond accuracy?
TL;DR
Apple provides a way to modify the behavior of measureBlock: by providing extra string constants but they don't support any string constants other than the default.
Long explanation
measureBlock calls the following function
- (void)measureMetrics:(NSArray *)metrics automaticallyStartMeasuring:(BOOL)automaticallyStartMeasuring withBlock:(void (^)(void))block;
//The implementation looks something like this (I can't say 100% but i'm pretty sure):
- (void)measureBlock:(void (^)(void))block {
NSArray<NSString *> *metrics = [[self class] defaultPerformanceMetrics];
[self measureMetrics:metrics automaticallyStartMeasure:YES withBlock:block];
}
defaultPerformanceMetrics is a class function that returns an array of strings.
From the Xcode source
"Subclasses can override this to change the behavior of
-measureBlock:"
Lovely, that sounds promising; we have customization behavior right? Well, they don't give you any strings to return. The default is XCTPerformanceMetric_WallClockTime ("com.apple.XCTPerformanceMetric_WallClockTime")
It turns out there aren't any string constants to return besides that one.
See the slides for WWDC 2014 Session 414 Testing in Xcode 6 (link).
I quote from page 158:
Currently supports one metric: XCTPerformanceMetric_WallClockTime
Nothing else has been added in Xcode 7 so it seems you're out of luck trying to modify measureBlock, sorry.
I've never found measureBlock: very useful. Check out Tidbits.xcodeproj/TidbitsTestBase/TBTestHelpers/comparePerformance https://github.com/tipbit/tidbits if you'd like to look at an alternative.
I am trying to fix a bug in an iPhone app, and find myself in front of this situation.
The instance variable myView is of type MYTextView, and MYTextView is a subclass of UITextView.
At the debugger I enter a few times in a row: p myView.text
the strange thing, as one can see below, is that I get different results:
(lldb) p myView.text
(NSString *) $34 = 0x095da870 #"พี(the-date-in-Thai-Language)
05"
(lldb) p myView.text
(NSString *) $35 = 0x0a2c5620 #"พี(the-date-in-Thai-Language)
"
(lldb) p myView.text
(NSString *) $36 = 0x09515f60 #"พี(the-date-in-Thai-Language)
щ"
(lldb) p myView.text
(NSString *) $37 = 0x09515f80 #"พี(the-date-in-Thai-Language)
㏀ड़ख़筀ज़툠ज़梐
⨈Ⴊ"
(lldb) p myView.text
(NSString *) $38 = 0x0a2c3800 #"พี(the-date-in-Thai-Language)
妜샷फ़"
(lldb) p myView.text
(NSString *) $39 = 0x095e7010 #"พี(the-date-in-Thai-Language)
"
Above the results $35 and $39 contain what I expect, the other lines contain garbage at the end of the expect string.
I don't understand how this changing garbage can be here, when I am supposed to be inside the debugger an pausing.
One more thing is that I am having this kind of problem only with the Thai language.
Does anyone have an idea of what could be going on?
This looks like a bug in the data formatter for NSString.
Are you on Xcode 4.6? If so I would love it if you filed a bug against Xcode with as much context as possible.
My guess is that there is some buffer that is not being managed properly.
When you use the p command, there are several different things lldb can do.
For simple concrete types (int, int *) it may only print the value in the variable (10, 0xffffffff83021600). It may have a formatter preference set (e.g. display the int in hexadecimal). It may have a more sophisticated python formatter (which can read different parts of memory and present a high-level view of the object to you). Finally, it may actually run code in your program to come up with a high level view of that variable.
In this case, with Xcode 4.6, this looks like a simple NSString ivar and so the expectation is that lldb can use its built-in python formatter for NSString objects. This built-in formatter looks at the object memory and knows how to reconstruct the actual string for display without running any code in your program. In which case, the content of the string should not be modified.
Earlier versions (and gdb) may run code in your program to format the string, and it is possible that the program could change a little in the process. There is a lot of work done to ensure that doesn't happen, but the possibility exists.
Enrico is suspecting that the built-in python formatter function for NSString may be misbehaving somehow in your program and providing string summaries that change as you re-call the formatter. Please do file a bug report at http://bugreport.apple.com/ with the details for how to reproduce this behavior.
I tried to convert GDATAXML Lib to ARC automatically with the refractor -> Convert to ARC Objective-C in XCode 4.2.
The ARC converter gives the following error:
result = [NSString stringWithUTF8String:(const char *) chars];
if (cacheDict) {
// save the string in the document's string cache
CFDictionarySetValue(cacheDict, chars, result);
}
error: Impicit conversion of Ojective-C pointer to void.
Has anyone succeeded in converting the GDATAXML Libs to ARC Objective-C?
please follow the instructions on how to make GDataXML work on your code: http://ibombsite.blogspot.com/2012/02/how-to-make-gdataxmlnode-work.html
I found someone who has (apparently successfully) done the refactor for ARC.
see: http://www.michaelbabiy.com/arc-compliant-gdataxml-library/
You need to use bridged cast:CFDictionarySetValue(cacheDict, chars, (__bridge_retained_void*) result);Check out Apple's article "Transitioning to ARC", especially the part about briding.
I wonder if Objective-C/Foundation has any special commands for reading user input from the console. Since it has NSLog for output maybe there is something else I could use instead of the scanf command.
I need to read some numbers (user input) into my tool. What is the best way to get these input in types like double or int? And how do I get user input into an NSString?
I was bored earlier and came across this issue of 'use scanf'. since I wanted to see if I could do it without dropping into c, the following came up:
NSFileHandle *input = [NSFileHandle fileHandleWithStandardInput];
while (1)
{
NSData* data = [input availableData];
if(data != nil)
{
NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
}
I'm sure somebody could optimize this and make it nicer (this was used for a really simple PoC CLI tool)
The only real Cocoa support for input is NSFileHandle's fileHandleWithStandardInput. It isn't really more useful than scanf() if you ask me. But for getting input into specific types, well, that's pretty much NSFormatter's thing. There are already a lot of predefined formatter types for standard things, and you can make a custom formatter if you have more specialized needs. So if you need something a little more than scanf(), just read in the data (either as bytes with scanf() or data with NSFileHandle) and make an NSString from it and you can format it to your heart's content.
Nothing like scanf (which is a good thing). You can slurp data from stdin using NSFileHandle; for interactive input, fgets is better. You'll then want to use either strtol/strtoul/strtod, NSScanner, or NSNumberFormatter to convert the input to numeric types.
NSString *aNSString;
CFStringRef aCFString;
aCFString = CFStringCreateWithCString(NULL, [aNSString UTF8String], NSUTF8StringEncoding);
aCFString = CFXMLCreateStringByUnescapingEntities(NULL, aCFString, NULL);
How can I get a new NSString from aCFString?
NSString and CFStringRef are "Toll free bridged", meaning that you can simply typecast between them.
For example:
CFStringRef aCFString = (CFStringRef)aNSString;
works perfectly and transparently. Likewise:
NSString *aNSString = (NSString *)aCFString;
The previous syntax was for MRC. If you're using ARC, the new casting syntax is as follows:
NSString *aNSString = (__bridge NSString *)aCFString;
works as well. The key thing to note is that CoreFoundation will often return objects with +1 reference counts, meaning that they need to be released (all CF[Type]Create format functions do this).
The nice thing is that in Cocoa you can safely use autorelease or release to free them up.
If you're using ARC in recent versions of Mac OS X/Objective C,
it's real easy:
NSString *happyString = (NSString *)CFBridgingRelease(sadString);
However, Xcode will happily warn you when you try to toll free bridge
CFString to NSString and offer to automatically wrap it in CFBridgingRelease(),
which you can accept and let it automatically insert the wrapper for you if you click the option.
They are equivalent, so you can just cast the CFStringRef:
NSString *aNSString = (NSString*)aCFString;
For more info, see Toll-Free Bridged Types.
Actually, you shouldn't use Cocoa retain, release, autorelease on Core Foundation objects in generality. If you're using Garbage Collection (only on Mac OS X for now), those retain, release, autorelease calls are all no-ops. Hence memory leaks.
From Apple http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcCoreFoundation.html:
It is important to appreciate the asymmetry between Core Foundation and Cocoa—where retain, release, and autorelease are no-ops. If, for example, you have balanced a CFCreate… with release or autorelease, you will leak the object in a garbage collected environment:
NSString *myString = (NSString *)CFStringCreate...(...);
// do interesting things with myString...
[myString release]; // leaked in a garbage collected environment
Conversely, using CFRelease to release an object you have previously retained using retain will result in a reference count underflow error.
PS: can't seem to comment on Peter Hosey's answer - sorry for adding my own unnecessarily.
I'll add that not only can you go from CFString to NSString with only a type-cast, but it works the other way as well. You can drop the CFStringCreateWithCString message, which is one fewer thing you need to release later. (CF uses Create where Cocoa uses alloc, so either way, you would have needed to release it.)
The resulting code:
NSString *escapedString;
NSString *unescapedString = [(NSString *) CFXMLCreateStringByUnescapingEntities(NULL, (CFStringRef) escapedString, NULL) autorelease];
I was having an issue with ARC and the retain count of CFStrings. Using NilObjects answer with a slight tweak worked perfect for me. I just added retained eg.
CFStringRef cfstringRef = (__bridge_retained CFStringRef)aNsString;
You have to cast it:
CFStringRef CFstringFileName=(__bridge CFStringRef)NSstringFileName;
Youcan use :With CFStringRef idc;
NSString *sId = [NSString stringWithFormat:#"%#", (NSString*)idc];