in a method that is accessed three times I want to write something to the log.
NSLog(#"%#", [response responseString]);
But there is nothing in the log. The log windows is completely white. Normally when I start an application there is always some stuff that shows up in the log but now it is totally empty.
How can I fix this?
Perhaps a really silly thing, but in the top right-corner of the console you should see this:
Check that the middle segment or right segment is selected.
NSString *responseString = [response responseString];
NSLog(#"%#", responseString);
set a breakpoint on the first line and debug the application to see if its coming in this code in the first place. If it is, hover over responseString and it will tell you whether it is nil or not.
When Console isn't behaving nicely for me (which happens sometimes when I'm doing driver level stuff or multi-threaded apps), a much more reliable thing to do is something like:
- (void) printToLog: (NSString *) aFormattedStringToPrint
{
// don't forget to remove an older copy of this file before
// your app finishes launching
FILE * aFile = fopen( "/tmp/debuggingoutput.txt", "a");
if(aFile)
{
fprintf(aFile, "%s", [aFormattedStringToPrint UTF8String];
fflush(aFile);
fclose(aFile);
}
}
(you can define a macro like LOGTHIS which might toggle between NSLog and the above more direct and to the point code)
And then you can "tail -f /tmp/debuggingoutput.txt" in your Terminal window while debugging and if nothing appears there, then you know your debugging lines aren't getting hit.
Today I have been frustrated with a similar problem. When the console is activated, only the variables pane is showing. No sign of the console pane. After finding Debug Area Help via right clicking in the variable pane, i could see that it is meant to sit next to it on the right.
The key for me was to Hide the Utilities panel. For me, the little buttons shown in Luke's answer above would not appear until hiding and unhiding the Utilites panel.
Related
I'm trying to get/set value from Summary Service application using this code
tell application "SummaryService"
activate
delay 0.1
get value of text area 1 of scroll area 1 of window "Summary"
end tell
And whatever I do (get or set) I get this error
Error image
(!) Generally, I'd like to find a way of launching Summary App with text as an argument (I want to add this possibility into my obj-c app). I've googled for some time and what I get is this one. Nevertheless it makes all the work behind scenes, giving to user only result of text transformation and makes to do some amount of unnecessary work, while I just want to launch default app.
Any help will be appreciated!
System Events can get windows, scroll areas and text areas, SummaryService can't.
tell application "SummaryService" to activate
delay 0.1
tell application "System Events"
tell application process "SummaryService"
get value of text area 1 of scroll area 1 of window "Summary"
end tell
end tell
Finally I don't solve my question in the way I previously want, but I found that there're many opensource summerize libs on github, so I use one
Just one moment since I want to use code written in Swift in my Objective-C project is to add
#import <Reductio/Reductio-Swift.h>
To controller where I want to implement desired functionality and call
[Reductio summarizeWithText:textToChange compression:compressionValue completion:^(NSArray<NSString *> * _Nonnull result) {}];
To get result.
PS: I still interested how to open SummaryService programmatically with text I choose.
PS 2: Suddenly I found such function as NSPerformService, which do exactly what I want. So I implement all the needed functionality in this way:
NSString *stringToSetInPb = #"sample text";
NSPasteboard *pb = [NSPasteboard pasteboardWithUniqueName];
[pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
[pb setString:stringToSetInPb forType:NSStringPboardType];
NSPerformService(#"Summarize", pb);
So question officially can be solved!
I'd like to move from NSLogging all over the place to using breakpoints for logging where the performance hit doesn't preclude it.
I know I can just po an object with a Debugger Command action, and I know I can just log any string by choosign the Log Message action.
And I think I should be able to combine both by choosing Log Message and entering something like SomeText giving context for object description: #(const char *)[[anObject description] UTF8String]#. Unfortunately, this doesn't seem to work, and always gives me what I assume to be the pointer to the description string.
What am I doing wrong?
It's kinda tricky but I think that this will work. Set the breakpoint Action as a debugger command. Then use this text as the action:
po (NSString *) [#"Some text describing: " stringByAppendingString:(NSString *)[anObject description]]
You must always be very careful to cast return types when working in the debugger. Both with GDB and LLDB.
I like your idea of using breakpoints to avoid the performance hit, but this also means that your logs will only be printed when connected to a debugger. While NSLogs will buffer their output to the system log, viewable from the Organizer (Devices) in Xcode.
(Edit: I missed the question's point and it's not an answer)
I think it's best to use DebugLog. It's a macro, and you can disable it easily (it's on when you def-ine DEBUG in your debug builds and is off when you don't define it). So, there's no performance degradation (quite the contrary).
Simply replace
NSLog(#"Hello, World!");
with
DebugLog(#"Hello, World!");
And instead of
19/4/12 8:55:52.949 PM Dictionary: Hello, World!
You'll get:
BetterDictionary.m:737 Hello, World!
(it shows which file and even which line has logged it)
Which is infinitely more interesting. undefine DEBUG for your production build and DebugLog won't be called at all.
And don't forget to #import 'DebugLog.h'.
I have written this trivial action method associated to a textfield.
Every time I enter text into a textfield a search in a PDF is performed and PDFView automatically scroll to selection:
- (IBAction) search:(id)id
{
NSString *query = [self.searchView stringValue]; // get from textfield
selection = [document findString: query fromSelection:NULL withOptions:NSCaseInsensitiveSearch];
if (selection != nil)
{
[self.pdfView setCurrentSelection:selection];
[self.pdfView scrollSelectionToVisible:self.searchView];
}
}
Problem is that after 3 or 4 searches I get EXC_BAD_ACCESS on row (i).
If I debug I see that query contains an NSCFString and not an NSString.
I think it is a memory management problem..but where?
I replicated the same issue inside a trivial testcase:
#interface PDFRef_protoTests : SenTestCase {
#private
PDFDocument *document;
}
........
- (void)setUp
{
[super setUp];
document = [[PDFDocument alloc] initWithURL: #"a local url ..."];
}
- (void)test_exc_bad_access_in_pdfdocument
{
for (int i =0 ;i<100; i++)
{
NSString *temp;
if (i % 2 == 0) temp = #"home";
else if (i % 3 ==0) temp = #"cocoa";
else temp=#"apple";
PDFSelection *selection = [document findString: temp
fromSelection:nil
withOptions:NSCaseInsensitiveSearch];
NSLog(#"Find=%#, iteration=%d", selection, i);
}
}
Update:
1) It seems that it happens also if I use asynchronous search (method beginFindString: withOptions) every time I perform second search.
2) I found a similar problem to mine in MacRuby Issue Tracking: http://www.macruby.org/trac/ticket/1029
3) It seems that if I disable temporarily garbage collection it works but memory goes up.
I wrote something like:
[[NSGarbageCollector defaultCollector] disable];
[[NSGarbageCollector defaultCollector] enable];
surrounding search code
Another Update
Very weird thing is that sometimes all works. Than I clean and Rebuild and problem arises again. From a certain point of view is is not 100% reproducible. I suspect a bug in PDFKit or some compiler setting I have to do
Update Again
Dears it seems very crazy. I'd concentrate on testcase which is very trivial and which replicates easily the problem. What's wrong with it? This testcase works only if I disable (by code or by project setting) GC
Another Update
Boys it seems a bug but I downloaded an example called PDFLinker from Apple website (http://developer.apple.com/library/mac/#samplecode/PDFKitLinker2/Introduction/Intro.html#//apple_ref/doc/uid/DTS10003594). This example implements a PDFViewer. Code of my app and this example are quite similars. For the same search action on same PDF, my memory rises at 300/400 MB while PDFLinker rises at 190MB. Clearly there is something wrong in my code. But I am comparing it bit by bit and I don't think I am inserting memory leaks (and Instrument doesn't give me any evidence). Maybe is there some project-wide setting ?
Update Yet
Changing from 64 bit to 32 bit memory consumption lowered. Surely there is a problem with 64bit and PDFKit. BTW still EXC_BAD_ACCESS on second search
SOLUTION
Crucial point is that PDFKit with Garbage collection is bugged.
If I disable GC all works correctly.
I had another issue that had complicated my analysis: I disabled GC on Project Setting but GC remained enabled on Target Settings. So Apple's example PDFLinked2 worked while mine not.
I agree you have found a bug in PDFKit.
I got various forms of errors (segmentation fault, selector not understood, etc) running your test case. Wrapping the code in #try/#catch doesn't prevent all errors associated with this method.
I also got errors printing the log message.
To work around the bug(s), I suggest you disable GC during your invocation of -findString:fromSelection:, as you've already discovered.
Also, be sure to make copies of the values of interest from selection before re-enabling GC. Don't just copy selection either.
If you conduct searches from multiple places in your code I also suggest you extract a separate method to perform the search. Then you can invoke that one to conduct the searches for you without duplicating the GC disable/enable nesting.
This sort of thing is usually evidence that you're hanging onto a pointer to an object that has been destroyed. Turn on zombie objects (with NSZombieEnabled) to see exactly where and when you're accessing a bad object.
Judging from your screen shot it doesn't seem like you have NSZombie turned on. Probably the reason why it doesn't help you. Here's how you turn it on:
How to enable NSZombie in Xcode?
The screenshot you provided was otherwise very useful, but you really need NSZombie to figure out this kind of errors. Well, unless it's obvious, which it isn't from the code you posted.
EDIT: I read the comment that you're using garbage collection. I'm an iOS developer, so I have very limited experience with garbage collection in Objective-C, but as far as I understand NSZombie doesn't work in a garbage collected environment.
I'm not sure it should be possible to get EXC_BAD_ACCESS in a garbage collected environment, unless you create your own pointer and try to call methods on it without having created an object and I don't see why you would do that.
I've heard that some frameworks doesn't work well with garbage collection, but I wouldn't think PDFKit was among them. Anyway, the solution might be to not use garbage collection. Perhaps you should file a bug report with Apple.
keep PDFSelection *selection as a member variable and pass it in fromSelection: instead of nil.
It is possible that PDFDocument keeps the returned PDFSelection instance to improve the performance.
Did you try retaining the searchview stringvalue object before using it?
As you say it happens when you type fast and it happens for async calls, it is possible that the object stringValue is pointing to is being released between the time your query object is pointing to it, and the time you use it int the search.
You could try something like this to see if the problem persists:
- (IBAction) search:(id)id
{
NSString *query = [[self.searchView stringValue] retain]; // get from textfield
selection = [document findString: query fromSelection:NULL withOptions:NSCaseInsensitiveSearch];
if (selection != nil)
{
[self.pdfView setCurrentSelection:selection];
[self.pdfView scrollSelectionToVisible:self.searchView];
}
[query release];
}
Of course there is also the possibility that document is relased. How do you declare it? is it a property with retain? Can it be released by the time you are searching?
EDIT:
I see that you posted the code with the second parameter as NULL, but in your screenshot, this value is nil.
The documentation says you should use NULL when you want to start the search from the beginning.
http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/QuartzFramework/Classes/PDFDocument_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40003873-RH2-DontLinkElementID_1
And as the compiler interprets nil and NULL differently, this could be leading to some weird behavior internally.
Sorry to bug twice so quickly, but since people were so kind in their informative responces, I figured it couldnt hurt to ask another question.
The same program i tried to make it rather swanky and have a main screen which allows you to click on a button which leads to a limited options screen. This lets you switch the music on or off. Or at least it should do.
The music running code is in the main file (game.m), under the following:
//Music
[Settings setMusicEnabled:YES];
music = [SPSound soundWithContentsOfFile:#"music.caf"];
channel = [[music createChannel] retain];
channel.loop = YES;
channel.volume = 0.25;
if([Settings musicEnabled]){
[channel play];
}
I apologize for the strange format, but it is Sparrow framework. basically, the Settings file contains the class methods I am trying to use. If the methods cause YES, the music is on. If it is No, then the music is off.
settings.m
static BOOL isMusicEnabled;
#implementation Settings
+ (BOOL)musicEnabled
{
return isMusicEnabled;
}
+ (void)setMusicEnabled:(BOOL)value
{
isMusicEnabled = value;
NSLog(#"SME? %i", isMusicEnabled);
}
#end
Now, the options file is working and i tested that section. The program is reading that isMusicEnabled is getting a new value, thus musicEnabled is being altered as well, so there should be a change and the music should be switched off.
However, nothing happens. I have tried to use debugger, but I am not very good at it and I dont understand a lot of the information i am given. I do understand that the problem is sending the message from Settings file to the main/Game file.
I would appriciate anyone's help who could enlighten me as to how this could be solved.
I'm not familiar with Sparrow Framework, but let me make a guess anyway.
[channel play]; starts playing the music in background until the channel is asked to stop playing.
Changing the isMusicEnabled does not trigger any code to stop the currently playing music. When you change the value in Settings, you should inform the channel to stop (most probably by somehow accessing the channel and calling [channel stop].
There's another problem - isMusicEnabled is just a variable in memory, your program will not remember its state between restarts. And Settings are usually supposed to be remembered.
To summarize I see two problems: persisting settings between restarts first and informing about change of settings second. To remember settings I suggest you look into NSUserDefaults class. To inform the channel to stop playing you have couple of options - depending on you skills. Easiest is to simply access the channel variable from within the setMusicEnabled and call stop. Another option would be to use notifications, but for a beginner programmer that is more complicated (look for NSNotificationCenter if interested).
I'm trying to print a PDFDocument that I am constructing from a series of images. In case it matters, I'm doing all of this from within a Mozilla plugin.
I create the PDFDocument, and put it into a PDFView, then I call
[printView printWithInfo: [NSPrintInfo sharedPrintInfo] autoRotate: YES];
The print dialog comes up (as a separate window, instead of panel. I assume that that comes from being inside a mozilla window, so I wasn't too worried about it. The dialog shows my document, and I can page through it correctly, and everything looks good.
However, when I hit "Print" the dropdown with "Layout" etc becomes empty, and the view under that becomes empty. The window doesn't disappear, and the document doesn't print. Hitting Cancel does exactly the same thing. The only thing I can do then is force-quit Mozillla.
I based the program off of PDFKitLinker2 from the apple dev site, and that program works. But I can't see any significant differences between it and my version.
Any suggestions on where to look?
thanks.
EDIT: Yes, I know that this is pretty much an exact duplicate of Printing Off-screen PDFViews but that never got a sufficient answer... (And I didn't notice it until just now...)
Sounds like you have a memory management issue here. Have you checked the console log to see if there's an exception being thrown? How are you creating your PDFView?
But why not do it the way WebKit does it?
Specifically, declare a category on PDFDocument
#interface PDFDocument (PDFSecretsIKnowViaWebKit)
- (NSPrintOperation *)getPrintOperationForPrintInfo:(NSPrintInfo *)printInfo autoRotate:(BOOL)doRotate;
#end
Then when you want to print your PDFDocument simply get an NSPrintOperation from it and run it.
NSPrintOperation *op = [myPDFDoc getPrintOperationForPrintInfo:info autoRotate:YES];
[op runOperation];
// [op runOperationModalForWindow:delegate:didRunSelector:contextInfo:] if you have a window to attach it to
This works for me too. I've verified that getPrintOperationForPrintInfo:autoRotate: exists and appears to work correctly on 10.4, 10.5 and 10.6.