Re: Scroll view within scroll view blocks scrolling

2011-05-14 Thread Philip Dow

On May 14, 2011, at 1:35 AM, William Squires wrote:

> 
> On Apr 28, 2011, at 6:12 PM, Indragie Karunaratne wrote:
> 
>> Despite the confusing title, I'm sure this is an issue that someone else has 
>> run into before. I have a parent scroll view that houses a bunch of 
>> subviews, including an NSTextView (and its own scroll view). The problem is 
>> that if I try to scroll vertically through the parent view, the text view's 
>> scroll view "blocks" my scrolling if I try to scroll while the cursor is 
>> within the text view. How can this be avoided?
> 
> It can't - all Mac programs do this - try loading a web page in Safari that 
> has a sub-block of text in the main page (that's too tall to display in the 
> parent window, thus requiring a scroller. You just have to watch out where 
> you put your cursor! :) I run across this often while researching on 
> wikipedia.org!
> 

It can, although you may end up creating additional problems for yourself which 
you'll need to work around.

You need a custom subview, probably whatever you're setting as the document 
view in your main scroll view. You can override the NSView hitTest: method so 
that it returns self whenever the point falls in one of the enclosed scroll 
views. This will cause all mouse events to be ignored by those sub scroll 
views, including scroll events.

Make sure you read up on this hitTest: method first. Overriding it incorrectly 
can seriously screw up your UI.

The problem: well, mouse events are also ignored in the enclosed text views, so 
that you can no longer select the text or click on links within that text 
without additional logic. If that isn't an issue, all the better.

Another solution, if it's an option, is to size the enclosed text views so that 
they always perfectly fit their content, which would let you disable all those 
lower level scroll views so that you don't run into this problem at all. The 
wonderfully complex NSLayoutManager provides the methods you need to determine 
how heigh a text storage needs to be to accommodate all its text, given a 
certain width. Have a look at usedRectForTextContainer:

~Phil

http://getsprouted.com

>> 
>> Thanks,
>> Indragie___
>> 
>> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
>> 
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>> 
>> Help/Unsubscribe/Update your Subscription:
>> http://lists.apple.com/mailman/options/cocoa-dev/wsquires%40satx.rr.com
>> 
>> This email sent to wsqui...@satx.rr.com
> 
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/dev%40getsprouted.com
> 
> This email sent to d...@getsprouted.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


NSPostWhenIdle not doing its job?

2011-05-14 Thread Jonathan Taylor
Hi folks,

This is inevitably a bit of a vague question, but I am hoping somebody may have 
some words of wisdom to offer nonetheless. The problem can be summarised as: in 
spite of having a backlog of notifications building up on the main thread, 
NSPostWhenIdle-qualified notifications do seem to be making it through. This is 
causing me problems because this idle work is swallowing up main thread time, 
making the backlog even worse! I am trying to understand why this is happening 
and whether I can do anything to alleviate the situation.

My code receives and processes frame data from a video camera driver. The 
sequence of events is as follows. It may seem a bit complicated, but I am 
including all the levels of indirection in case that proves to be relevant, 
rather than simplifying things too much.

- From the driver callback I post a block (function A) onto a custom GCD 
queue(this extra level of indirection is important because I cannot do 
*anything* in the driver callback that may cause it to take more than the bare 
minimum of time - and that includes allocating any memory, even!).
- Function A may do a number of things, but in this case all it does is posts 
two notifications to the application main thread (this is necessary for 
subscribers that may modify the GUI etc). Notification 1 is queued as normal, 
and Notification 2 is posted with the NSPostWhenIdle qualifier
- Function B subscribes to notification 1. Again, it may do a number of things 
but in this case all it does here is request that the data be saved to disk 
(the actual saving is done in a separate thread to avoid holding up the main 
thread).
- Function C subscribes to notification 2 (which, to emphasize again, should be 
being coalesced and posted when the main thread is idle). Function C updates 
the GUI to reflect the frame image most recently processed [by function B]

My intention with this is that this should prioritize the "important" bits of 
the code, but that if there are still spare CPU cycles available then this time 
is used by Function C to draw in the GUI.

The actual code used to post a coalesced notification (NSPostWhenIdle) is as 
follows:
void QueueNotificationOnMainThreadWithCoalescing(const NSString 
*notificationName, NSPostingStyle style, id obj)
{
NSNotification *myNotification = [NSNotification 
notificationWithName:notificationName object:obj];
[[NSOperationQueue mainQueue] addOperationWithBlock:
^{
[[NSNotificationQueue defaultQueue]
enqueueNotification:myNotification
postingStyle:style

coalesceMask:NSNotificationCoalescingOnName|NSNotificationCoalescingOnSender
forModes:[NSArray 
arrayWithObject:NSRunLoopCommonModes]];   
}];
}



If Function B does nothing (i.e. does not write to disk), then as CPU load 
increases the image as viewed in the GUI becomes jerky or stops updating 
altogether, indicating that PostWhenIdle is doing its throttling job correctly.

However if Function B does cause the data to be saved to disk then things do 
not work as expected, even in the absence of any non-essential CPU load. A 
backlog of Notification 1 events builds up on the main thread - i.e. the main 
thread is not managing to keep up with the rate at which frames are coming in 
and notifications are being posted. In spite of this, Function C *is* being 
called at regular intervals and the GUI is kept updated and looks smooth. There 
is however the outward symptom that the image shown in the GUI does not reflect 
the actual real-world reality because all it can show is the most recent frame 
that has actually been processed (and there is a backlog) - in other words if 
the camera is pointed at a clock then the image of the clock in the GUI will 
apparently be running "slow" compared to the real world clock.


For what it's worth, on the core 2 duo macbook where I see the problems the CPU 
load reported by Shark is:
start   39.0%   [the main thread]
unix_syscall27.7%   [which appears to be associated with 
saving to disk]
user_trap   8.4%[looks like mostly VM-related]
start_wqthread  8.2%[various functions of mine, including function 
A and the one that does the actual saving to disk]
thread_start6.8%[the camera driver library]

Shark system trace shows plenty going on both on the main thread and on 
numerous other threads of mine. However the main thread spends the vast 
majority of the time blocked on [NSWindow displayIfNeeded]! This is what is 
causing the massive bottleneck on the main thread. Because there is a backlog 
on the main thread we should NOT be getting postWhenIdle notifications, but 
because we do we are doing the drawing, which is what is holding the main 
thread up in the first place! Somehow, the NSPost

Re: Can't create temporary file

2011-05-14 Thread Fritz Anderson
On 14 May 2011, at 12:46 AM, Rick Mann wrote:

>NSError* err = nil;
>NSURL* tempDir = [fm URLForDirectory: NSItemReplacementDirectory
>inDomain: NSUserDomainMask
>appropriateForURL: inURL
>create: true
>error: &err];
>if (err != nil)
>{
>NSLog(@"Error creating temporary directory for URL %@: %@", inURL, 
> err);
>return;
>}

[similar check of err later in the code]

Quincey Morris identified your problem, but you can't do this. Methods that 
take NSError** are entitled to fill in the error return even if they succeed. 
Always check the principal return value (tempDir being nil, here) and _then_ 
you'll know that the NSError represents the actual description of a problem.


— F

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


create an autorelease pool in the init-method and release it in the dealloc-method ..?

2011-05-14 Thread Martin Batholdy
Hi,


I still have trouble understanding the autorelease pool.

Lets assume an object Z has a method where it gets a string y and returns 
another string x.

Now when an instance of this object is created and the method is invoked,
 x is returned and is used somewhere else.

Now this method of object Z should not be the owner of x right?
Because x is used elsewhere.


So I add x to the autorelease-pool to declare that I am not the owner (and 
won't send it a release message);

x = [[[NSString alloc] init] autorelease];


but where do I release the pool?
And to which pool is it added?


I thought I would create my own pool in the init-method of Z and send it a 
[pool release] message in the alloc-method.

But I haven't seen that so far in sample code ...



can someone explain me what happens when I add x to the autorelease pool?
And where does it get released when I don't send a release command to the pool?

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: create an autorelease pool in the init-method and release it in the dealloc-method ..?

2011-05-14 Thread Nick Zitzmann

On May 14, 2011, at 5:43 PM, Martin Batholdy wrote:

> I still have trouble understanding the autorelease pool.
> 
> Lets assume an object Z has a method where it gets a string y and returns 
> another string x.
> 
> Now when an instance of this object is created and the method is invoked,
> x is returned and is used somewhere else.
> 
> Now this method of object Z should not be the owner of x right?
> Because x is used elsewhere.
> 
> 
> So I add x to the autorelease-pool to declare that I am not the owner (and 
> won't send it a release message);
> 
> x = [[[NSString alloc] init] autorelease];
> 
> 
> but where do I release the pool?
> And to which pool is it added?

Pay attention to the memory management rules: 


> I thought I would create my own pool in the init-method of Z and send it a 
> [pool release] message in the alloc-method.
> 
> But I haven't seen that so far in sample code ...

Don't ever do that. You'll wind up popping objects that aren't supposed to be 
popped yet, which will lead to a crash. Autorelease pools should never be used 
as ivars, globals, or static variables.

In general, you shouldn't create your own autorelease pools, unless (1) you are 
using NSThread or pthread to create new threads, or (2) you have written a loop 
that generates a great deal of temporary objects that need to be popped from 
time to time to keep memory usage from spiking, and you know what you're doing.

> can someone explain me what happens when I add x to the autorelease pool?

Read the autorelease pools article in the memory management programming guide 
(see link above) and it will clear things up.

Nick Zitzmann




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: create an autorelease pool in the init-method and release it in the dealloc-method ..?

2011-05-14 Thread Dave Zarzycki
Here is a trick to help you better understand how to use autorelease pools 
correctly. Put this in a header somewhere:

static inline void subpool(void (^block)(void))
{
NSAutoreleasePool *_pool = [[NSAutoreleasePool alloc] init];
block();
[pool drain];
}

… and use it like so:

subpool(^{
// do stuff
});

And if you need to get stuff out of a subpool:

__block NSThingy *t = nil;
subpool(^{
t = [other getThingy];
[t retain]; // because getThingy might return autoreleased
});
[t doSomething];
[t release]; // balance the earlier retain
t = nil;



On May 14, 2011, at 6:19 PM, Nick Zitzmann wrote:

> 
> On May 14, 2011, at 5:43 PM, Martin Batholdy wrote:
> 
>> I still have trouble understanding the autorelease pool.
>> 
>> Lets assume an object Z has a method where it gets a string y and returns 
>> another string x.
>> 
>> Now when an instance of this object is created and the method is invoked,
>> x is returned and is used somewhere else.
>> 
>> Now this method of object Z should not be the owner of x right?
>> Because x is used elsewhere.
>> 
>> 
>> So I add x to the autorelease-pool to declare that I am not the owner (and 
>> won't send it a release message);
>> 
>> x = [[[NSString alloc] init] autorelease];
>> 
>> 
>> but where do I release the pool?
>> And to which pool is it added?
> 
> Pay attention to the memory management rules: 
> 
> 
>> I thought I would create my own pool in the init-method of Z and send it a 
>> [pool release] message in the alloc-method.
>> 
>> But I haven't seen that so far in sample code ...
> 
> Don't ever do that. You'll wind up popping objects that aren't supposed to be 
> popped yet, which will lead to a crash. Autorelease pools should never be 
> used as ivars, globals, or static variables.
> 
> In general, you shouldn't create your own autorelease pools, unless (1) you 
> are using NSThread or pthread to create new threads, or (2) you have written 
> a loop that generates a great deal of temporary objects that need to be 
> popped from time to time to keep memory usage from spiking, and you know what 
> you're doing.
> 
>> can someone explain me what happens when I add x to the autorelease pool?
> 
> Read the autorelease pools article in the memory management programming guide 
> (see link above) and it will clear things up.
> 
> Nick Zitzmann
> 
> 
> 
> 
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/zarzycki%40apple.com
> 
> This email sent to zarzy...@apple.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Tab Bar Application

2011-05-14 Thread koko
Given a Tab Bar Application with n Tab Bar Items what is the recommended 
pattern for the Views associated with each Tab Bar Item to communicate between 
themselves?

koko

"Don't fight the framework."
--Kyle Sluder

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: create an autorelease pool in the init-method and release it in the dealloc-method ..?

2011-05-14 Thread Martin Batholdy
thanks!

Perhaps my confusion comes from reading about autorelease pools in an 
objective-c books that focuses on command-line program.

So if I understood it correctly; 
(based on  
)
whenever I add an object to the autorelease pool or don't own the object it 
gets released automatically after an event cycle.

is that correct?

So I only have to worry about objects I own, that are objects I allocate with 
alloc
(I don't use new or copy anywhere).


On 15.05.2011, at 03:19, Nick Zitzmann wrote:

> 
> On May 14, 2011, at 5:43 PM, Martin Batholdy wrote:
> 
>> I still have trouble understanding the autorelease pool.
>> 
>> Lets assume an object Z has a method where it gets a string y and returns 
>> another string x.
>> 
>> Now when an instance of this object is created and the method is invoked,
>> x is returned and is used somewhere else.
>> 
>> Now this method of object Z should not be the owner of x right?
>> Because x is used elsewhere.
>> 
>> 
>> So I add x to the autorelease-pool to declare that I am not the owner (and 
>> won't send it a release message);
>> 
>> x = [[[NSString alloc] init] autorelease];
>> 
>> 
>> but where do I release the pool?
>> And to which pool is it added?
> 
> Pay attention to the memory management rules: 
> 
> 
>> I thought I would create my own pool in the init-method of Z and send it a 
>> [pool release] message in the alloc-method.
>> 
>> But I haven't seen that so far in sample code ...
> 
> Don't ever do that. You'll wind up popping objects that aren't supposed to be 
> popped yet, which will lead to a crash. Autorelease pools should never be 
> used as ivars, globals, or static variables.
> 
> In general, you shouldn't create your own autorelease pools, unless (1) you 
> are using NSThread or pthread to create new threads, or (2) you have written 
> a loop that generates a great deal of temporary objects that need to be 
> popped from time to time to keep memory usage from spiking, and you know what 
> you're doing.
> 
>> can someone explain me what happens when I add x to the autorelease pool?
> 
> Read the autorelease pools article in the memory management programming guide 
> (see link above) and it will clear things up.
> 
> Nick Zitzmann
> 
> 
> 
> 

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: NSPostWhenIdle not doing its job?

2011-05-14 Thread Ken Thomases
On May 14, 2011, at 11:46 AM, Jonathan Taylor wrote:

> The problem can be summarised as: in spite of having a backlog of 
> notifications building up on the main thread, NSPostWhenIdle-qualified 
> notifications do seem to be making it through. This is causing me problems 
> because this idle work is swallowing up main thread time, making the backlog 
> even worse! I am trying to understand why this is happening and whether I can 
> do anything to alleviate the situation.

I suspect you have assumed things about NSPostWhenIdle and NSPostASAP which 
just aren't true.  In particular, you think that the former is "prioritized" 
lower than the latter.  However, they just indicate different points during a 
run loop's execution when the notifications are delivered.

Notifications queued with NSPostWhenIdle are posted when the run loop is idle 
-- when it would otherwise put the thread to sleep waiting for something to 
happen.  Those queued with NSPostASAP are posted after an input source or timer 
is serviced (when it's handling function or method returns).

If no input sources or timers are firing, then notifications posted with 
NSPostASAP may not fire soon.  Unfortunately, operations being queued or run in 
the main queue don't count, it would seem.  At least, I think that's what's 
happening.

You may also be running into this issue, somehow: 
.  NSOperationQueue's 
+mainQueue presumably uses dispatch_get_main_queue() under the hood.

One obvious improvement to your scheme is, since Function C should not do 
anything unless and until Function B has processed a new frame image, post its 
notification (notification 2) from Function B, not Function A.  (Or otherwise 
arrange for Function C to be triggered by Function B's completion.)

Still, that won't help if Function B is not being called as often as you expect 
because NSPostASAP doesn't work like you thought.  I suspect that it is only 
being called when something else tickles the run loop, like user events.  I 
wonder if you click-and-hold in your window (not necessarily on a button or any 
active control) and just keep dragging the mouse back and forth, if that helps 
keep the backlog clear.  (Simple mouse moves without the mouse button don't 
send events unless your window has specifically subscribed to them using 
NSTrackingArea or -setAcceptsMouseMovedEvents:.)

Regards,
Ken

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: create an autorelease pool in the init-method and release it in the dealloc-method ..?

2011-05-14 Thread Nick Zitzmann

On May 14, 2011, at 8:20 PM, Martin Batholdy wrote:

> So if I understood it correctly; 
> (based on  
> )
> whenever I add an object to the autorelease pool or don't own the object it 
> gets released automatically after an event cycle.
> 
> is that correct?

Almost. Whenever an object is added to the autorelease pool, it gets released 
when that autorelease pool pops. NSApplication and UIApplication just happen to 
wrap their event cycles in an autorelease pool.

Nick Zitzmann




___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com